web-dev-qa-db-fra.com

Instance de mise en scène ou de production?

Y a-t-il un endroit de l'exécution du service qui me dirait si je suis actuellement en cours d'exécution ou de production? La modification manuelle de la configuration depuis et vers la production semble un peu lourde.

46
Kenji

Vous ne devriez vraiment pas changer vos configurations lorsque vous êtes basé sur si vous êtes en production ou en mise en scène. La zone de transit n'est pas conçue pour être un environnement "AQ" mais uniquement une zone d'attente avant le déploiement de la production.

Lorsque vous téléchargez un nouveau déploiement, l'emplacement de déploiement actuel dans lequel vous téléchargez votre package est détruit et est arrêté pendant 10 à 15 minutes pendant le téléchargement et le démarrage des VM. Si vous téléchargez directement en production, cela représente 15 minutes d'arrêt de production. Ainsi, la zone de transfert a été inventée: vous téléchargez vers le transfert, testez le contenu et cliquez sur le bouton "Swap" et votre environnement de transfert devient comme par magie la production (échange IP virtuel). Ainsi, votre mise en scène doit vraiment être 100% identique à votre production.

Ce que je pense que vous recherchez, c'est un environnement QA/test? Vous devez ouvrir un nouveau service pour l'environnement de test avec son propre Prod/Staging. Dans ce cas, vous souhaiterez conserver plusieurs ensembles de fichiers de configuration, un ensemble par environnement de déploiement (Production, Test, etc.)

Il existe de nombreuses façons de gérer l'enfer de configuration qui se produit, en particulier avec Azure qui a au-dessus des fichiers .config, ses propres fichiers * .cscfg. La façon dont je préfère le faire avec le projet Azure est la suivante: configurez un petit projet de configuration, créez-y des dossiers qui correspondent aux types de déploiement. À l'intérieur de chaque dossier, des ensembles de fichiers * .config et * .cscfg qui correspondent à un environnement de déploiement particulier: débogage, test, version ... ceux-ci sont également configurés dans Visual Studio, ainsi que les types de cible de génération. J'ai une petite commande xcopy qui se produit lors de chaque compilation du projet Config qui copie tous les fichiers du dossier Build Target du projet Config dans le dossier racine du projet Config.

Ensuite, tous les autres projets de la solution, LIENS au fichier .config ou .cscfg du dossier racine du projet Config.

Voila, mes configs s'adaptent comme par magie à chaque configuration de build automatiquement. J'utilise également des transformations .config pour gérer les informations de débogage pour les cibles de build Release vs non-Release.

Si vous avez lu tout cela et que vous souhaitez toujours obtenir l'état Production vs Staging à l'exécution , alors: Obtenez deploymentId à partir de RoleEnvironment.DeploymentId Utilisez ensuite l'API de gestion avec un X509 certificate Approprié pour accéder au Azure structure of your Service Et appelez la méthode GetDeployments (c'est l'api de repos mais il y a une bibliothèque d'abstraction) .

J'espère que cela t'aides

Modifier: article de blog comme demandé sur la configuration des chaînes de configuration et la commutation entre les environnements @ http://blog.paraleap.com/blog/post/Managing-environments-in-a-distributed-Azure-or-other -cloud-based-NET-solution

77
Igorek

Parfois, je souhaite que les gens répondent simplement à la question ... sans expliquer l'éthique ou les meilleures pratiques ...

Microsoft a publié un exemple de code faisant exactement cela ici: https://code.msdn.Microsoft.com/windowsazure/CSAzureDeploymentSlot-1ce0e3b5

image showing Staging instance

image showing Production instance

protected void Page_Load(object sender, EventArgs e) 
{ 
    // You basic information of the Deployment of Azure application. 
    string deploymentId = RoleEnvironment.DeploymentId; 
    string subscriptionID = "<Your subscription ID>"; 
    string thrumbnail = "<Your certificate thumbnail print>"; 
    string hostedServiceName = "<Your hosted service name>"; 
    string productionString = string.Format(
        "https://management.core.windows.net/{0}/services/hostedservices/{1}/deploymentslots/{2}",
        subscriptionID, hostedServiceName, "Production"); 
    Uri requestUri = new Uri(productionString); 

    // Add client certificate. 
    X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
    store.Open(OpenFlags.OpenExistingOnly); 
    X509Certificate2Collection collection = store.Certificates.Find(
        X509FindType.FindByThumbprint, thrumbnail, false); 
    store.Close(); 

    if (collection.Count != 0) 
    { 
        X509Certificate2 certificate = collection[0]; 
        HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(requestUri); 
        httpRequest.ClientCertificates.Add(certificate); 
        httpRequest.Headers.Add("x-ms-version", "2011-10-01"); 
        httpRequest.KeepAlive = false; 
        HttpWebResponse httpResponse = httpRequest.GetResponse() as HttpWebResponse;

        // Get response stream from Management API. 
        Stream stream = httpResponse.GetResponseStream(); 
        string result = string.Empty; 
        using (StreamReader reader = new StreamReader(stream)) 
        { 
            result = reader.ReadToEnd();
        } 
        if (result == null || result.Trim() == string.Empty) 
        {
            return;
        }
        XDocument document = XDocument.Parse(result); 
        string serverID = string.Empty; 
        var list = from item
                   in document.Descendants(XName.Get("PrivateID",
                       "http://schemas.Microsoft.com/windowsazure")) 
                   select item; 

        serverID = list.First().Value; 
        Response.Write("Check Production: "); 
        Response.Write("DeploymentID : " + deploymentId
            + " ServerID :" + serverID); 
        if (deploymentId.Equals(serverID)) 
            lbStatus.Text = "Production"; 
        else 
        { 
            // If the application not in Production slot, try to check Staging slot. 
            string stagingString = string.Format(
                "https://management.core.windows.net/{0}/services/hostedservices/{1}/deploymentslots/{2}",
                subscriptionID, hostedServiceName, "Staging"); 
            Uri stagingUri = new Uri(stagingString); 
            httpRequest = (HttpWebRequest)HttpWebRequest.Create(stagingUri); 
            httpRequest.ClientCertificates.Add(certificate); 
            httpRequest.Headers.Add("x-ms-version", "2011-10-01"); 
            httpRequest.KeepAlive = false; 
            httpResponse = httpRequest.GetResponse() as HttpWebResponse; 
            stream = httpResponse.GetResponseStream(); 
            result = string.Empty; 
            using (StreamReader reader = new StreamReader(stream)) 
            { 
                result = reader.ReadToEnd();
            } 
            if (result == null || result.Trim() == string.Empty) 
            {
                return;
            }
            document = XDocument.Parse(result); 
            serverID = string.Empty; 
            list = from item
                   in document.Descendants(XName.Get("PrivateID",
                       "http://schemas.Microsoft.com/windowsazure")) 
                   select item; 

            serverID = list.First().Value; 
            Response.Write(" Check Staging:"); 
            Response.Write(" DeploymentID : " + deploymentId
                + " ServerID :" + serverID); 
            if (deploymentId.Equals(serverID)) 
            {
                lbStatus.Text = "Staging";
            }
            else 
            {
                lbStatus.Text = "Do not find this id";
            }
        } 
        httpResponse.Close(); 
        stream.Close(); 
    } 
}
51
artfulhacker

Le staging est un emplacement de déploiement temporaire utilisé principalement pour les mises à niveau sans interruption et la possibilité de restaurer une mise à niveau.

Il est conseillé de ne pas coupler votre système (que ce soit en code ou en configuration) avec ces spécificités Azure.

8
Rinat Abdullin

Depuis Bibliothèques de gestion Windows Azure et grâce à @GuaravMantri réponse à une autre question, vous pouvez le faire comme ceci:

using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Azure;
using Microsoft.WindowsAzure.Management.Compute;
using Microsoft.WindowsAzure.Management.Compute.Models;

namespace Configuration
{
    public class DeploymentSlotTypeHelper
    {
        static string subscriptionId = "<subscription-id>";
        static string managementCertContents = "<Base64 Encoded Management Certificate String from Publish Setting File>";// copy-paste it
        static string cloudServiceName = "<your cloud service name>"; // lowercase
        static string ns = "http://schemas.Microsoft.com/ServiceHosting/2008/10/ServiceConfiguration";

        public DeploymentSlot GetSlotType()
        {
            var managementCertificate = new X509Certificate2(Convert.FromBase64String(managementCertContents));
            var credentials = new CertificateCloudCredentials(subscriptionId, managementCertificate);

            var computeManagementClient = new ComputeManagementClient(credentials);
            var response = computeManagementClient.HostedServices.GetDetailed(cloudServiceName);
            return response.Deployments.FirstOrDefault(d => d.DeploymentSlot == DeploymentSlot.Production) == null ? DeploymentSlot.Staging : DeploymentSlot.Production;
        }
    }
}
5
Ognyan Dimitrov

Un moyen simple de résoudre ce problème consiste à définir sur vos instances une clé pour identifier l'environnement dans lequel il s'exécute.

1) Définissez à votre emplacement de production: Définissez-le Paramètres >> Paramètres d'application >> Paramètres d'application Et créez une clé nommée SLOT_NAME et valeur "production". IMPORTANT: vérifiez le réglage de l'emplacement.

2) Définissez à votre emplacement intermédiaire: Définissez-le Paramètres >> Paramètres d'application >> Paramètres d'application Et créez une clé nommée SLOT_NAME et valeur "staging". IMPORTANT: vérifiez le réglage de l'emplacement.

Accédez à partir de votre application à la variable et identifiez l'environnement dans lequel l'application s'exécute. Dans Java vous pouvez accéder:

String slotName = System.getenv("APPSETTING_SLOT_NAME");
4

Voici 4 points à considérer

  1. L'échange VIP n'a de sens que lorsque votre service fait face au monde extérieur. AKA, lorsqu'il expose une API et réagit aux demandes.
  2. Si tout votre service consiste à extraire des messages d'une file d'attente et à les traiter, vos services sont proactifs et VIP swap n'est pas une bonne solution pour vous.
  3. Si votre service est à la fois réactif et proactif, vous voudrez peut-être reconsidérer votre conception. Peut-être diviser le service en 2 services différents.
  4. La suggestion d'Eric de modifier les fichiers cscfg avant et après VIP est bon si la partie proactive de votre service peut prendre un temps d'arrêt court (Parce que vous configurez d'abord Staging et Production pour ne pas tirer messages, puis effectuez VIP Swap, puis mettez à jour la configuration de Production pour commencer à extraire les messages).
1
Ash Saf