2010-12-01 7 views
45

Y a-t-il quelque part dans l'exécution du service qui me dirait si je cours actuellement sur 'Staging' ou 'Production'? Modifier manuellement la config de et vers la production semble un peu lourd.Instance de transfert ou de production?

Répondre

75

Vous ne devriez vraiment pas changer vos configurations lorsque vous êtes basé sur si vous êtes dans Prod ou Staging. La zone de stockage n'est pas conçue pour être un environnement «AQ» mais seulement une zone de stockage avant le déploiement de la production. Lorsque vous téléchargez un nouveau déploiement, l'emplacement de déploiement en cours dans lequel vous téléchargez votre paquet est détruit et reste inactif pendant 10 à 15 minutes pendant le téléchargement et le démarrage des machines virtuelles. Si vous téléchargez directement en production, cela représente 15 minutes d'arrêt de production. Ainsi, la zone de stockage a été inventée: vous téléchargez vers la mise en scène, testez la substance, et cliquez sur le bouton "Swap" et votre environnement Staging devient magiquement Production (échange IP virtuel). Ainsi, votre mise en scène devrait être 100% identique à votre production.

Ce que je pense que vous cherchez est un environnement de test/d'assurance qualité? Vous devriez ouvrir un nouveau service pour l'environnement de test avec son propre Prod/Staging. Dans ce cas, vous devez gérer plusieurs jeux de fichiers de configuration, un jeu par environnement de déploiement (Production, Tests, etc.)

Il existe plusieurs façons de gérer la configuration-enfer, en particulier avec Azure qui a le 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 là des dossiers qui correspondent aux types de déploiement. À l'intérieur de chaque dossier d'installation de fichiers * .config & * .cscfg qui correspondent à un environnement de déploiement particulier: Déboguer, Tester, Libérer ... ceux-ci sont également installés dans Visual Studio, en tant que types de cible de construction. 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.

Puis tous les autres projets de la solution, LINKS au fichier .config ou .cscfg à partir du dossier racine du projet Config. Voila, mes configs s'adaptent automatiquement à chaque configuration de construction automatiquement. J'utilise également les transformations .config pour gérer les informations de débogage pour les cibles de version Release et non-Release.

Si vous avez lu tout cela et que vous voulez toujours obtenir à la production par rapport à l'état de mise en attente à l'exécution, puis: Get deploymentId de RoleEnvironment.DeploymentId Ensuite, utilisez l'API de gestion avec une X509 certificate appropriée pour obtenir au Azure structure of your Service et appelez la méthode GetDeployments (c'est repos api mais il y a une bibliothèque d'abstraction).

Hope this helps

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

+2

Salut Igorek, pouvez-vous s'il vous plaît nous fournir quelques exemples de code ou des conseils étape par étape avec elle? J'ai aussi des problèmes avec web.config dans Azure par environnement .... –

+1

+1 pour Igorek pour écrire un article de blog à ce sujet :) – Slav

+6

Huit mois plus tard, mais le voici: http://www.paraleap.com/ blog/post/Gestion des environnements-dans-un-distribué-Azure-ou-autre-basée sur le cloud-NET-solution.aspx – Igorek

8

Mise en scène est une fente de déploiement temporaire utilisé principalement pour des mises à niveau sans interruption de service et la capacité à rouler retourner une mise à niveau.

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

+38

C'est très bien, sauf lorsque vos services retirent des tâches d'une file d'attente et provoquent des effets secondaires avant d'échanger des VIP, sauf si vous avez un moyen de leur dire de ne pas le faire quand ils sont en transit. Dans ce cas, vous avez besoin d'un moyen de dire à votre service de ne pas faire ce genre de choses avant d'arriver à la production. – Jaxidian

+8

Exactement, quel est le problème que j'ai. Mon rôle de travail obtient des événements de ma file d'attente de bus de service lorsqu'un nouveau message arrive. Je ne veux pas qu'il s'agisse de la "vraie" file d'attente de production jusqu'à ce qu'il arrive dans le "vrai" environnement de production, donc vous n'êtes pas le seul à avoir ce problème. – Michael

+2

Cela a été la position de Microsoft tout au long, et même si idéal et puriste, ne fonctionne pas pour les raisons énoncées ci-dessus. Nous modifions simplement le swap cscfg pré- et post-VIP avec une valeur qui indique l'emplacement de l'instance. Simple, fiable et facile. – Eric

1

Voici 4 points à considérer

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

Parfois, je voudrais que les gens simplement répondre à la question .. ne pas expliquer l'éthique ou les meilleures pratiques ...

Microsoft a posté un exemple de code fait 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(); 
    } 
} 
+10

Merci d'avoir répondu à la question. –

+2

"Parfois, je souhaite que les gens répondent à la question .. ne pas expliquer l'éthique ou les meilleures pratiques ..." - Amen frère –

5

Depuis Windows Azure Management Libraries et grâce à @GuaravMantri answer à 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; 
     } 
    } 
} 
2

Un moyen facile de résoudre ce problème est DURCISSEMENT à vos instances une clé pour identifier quel environnement il est en cours d'exécution.

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

2) Définissez sur votre emplacement de stockage intermédiaire: Définissez-le Paramètres >> Paramètres de l'application >> Paramètres de l'application Et créez une clé nommée SLOT_NAME et une 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. En Java, vous pouvez accéder à:

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