2010-12-01 1 views
45

Gibt es irgendwo in der Service-Laufzeit, die mir sagen würde, ob ich gerade auf "Staging" oder "Produktion" läuft? Manuelles Ändern der Konfiguration zur und von der Produktion scheint etwas umständlich.Inszenierungs- oder Produktionsinstanz?

Antwort

75

Sie sollten Ihre Konfigurationen wirklich nicht ändern, wenn Sie auf Prod oder Staging basieren. Der Staging-Bereich ist nicht als "QA" -Umgebung konzipiert, sondern nur als Haltebereich, bevor die Produktion eingesetzt wird.

Wenn Sie eine neue Bereitstellung hochladen, wird der aktuelle Bereitstellungssteckplatz, auf den Sie Ihr Paket hochladen, zerstört und ist 10-15 Minuten lang inaktiv, während das Hochladen und Starten von VMs stattfindet. Wenn Sie direkt in die Produktion hochladen, sind das 15 Minuten Produktionsstillstand. Daher wurde der Staging-Bereich erfunden: Sie laden ins Staging hoch, testen das Zeug und klicken auf "Swap", und Ihre Staging-Umgebung wird auf magische Weise zur Produktion (virtueller IP-Swap). Ihre Inszenierung sollte also zu 100% mit Ihrer Produktion identisch sein.

Was ich denke, Sie suchen, ist QA/Testumgebung? Sie sollten einen neuen Dienst für die Testumgebung mit einem eigenen Prod/Staging öffnen. In diesem Fall sollten Sie mehrere Konfigurationsdateisätze verwalten, einen Satz pro Implementierungsumgebung (Produktion, Testen usw.).

Es gibt viele Möglichkeiten zur Verwaltung der Konfigurationshölle, insbesondere bei Azure, das oben angezeigt wird von .config-Dateien, seine eigenen * .cscfg-Dateien. Die Art, wie ich es mit Azure-Projekt bevorzuge, ist wie folgt: Richten Sie ein kleines Konfigurationsprojekt ein, erstellen Sie dort Ordner, die den Bereitstellungstypen entsprechen. Innerhalb jedes Ordners Setup-Sets von * .config & * .cscfg Dateien, die zu bestimmten Einsatzumgebung passen: Debug, Test, Release ... diese sind auch in Visual Studio als Build-Zieltypen eingerichtet. Ich habe einen kleinen xcopy-Befehl, der bei jedem Kompilieren des Konfigurationsprojekts auftritt, das alle Dateien aus dem Ordner "Build Target" des Konfigurationsprojekts in den Stammordner des Konfigurationsprojekts kopiert.

Dann jedes andere Projekt in der Lösung, LINKS zu der .config oder .cscfg Datei aus dem Stammordner des Config-Projekts.

Voila, meine Konfigurationen passen sich automatisch jeder Build-Konfiguration automatisch an. Ich verwende auch .config-Transformationen, um Debugging-Informationen für Release-Build-Ziele im Vergleich zu Nicht-Release-Build-Zielen zu verwalten.

Wenn Sie all dies lesen und wollen noch in der Produktion vs. Staging Status, zur Laufzeit dann erhalten: Erhalten deploymentId von RoleEnvironment.DeploymentId Dann Management API mit einer richtigen X509 certificate verwenden am Azure structure of your Service zu bekommen und Rufen Sie die GetDeployments Methode auf (es ist Ruhe-API, aber es gibt eine Abstraktionsbibliothek).

this helps

Edit: Blog-Post, wie etwa die Einrichtung von Konfigurationsstrings angefordert und das Umschalten zwischen Umgebungen @http://blog.paraleap.com/blog/post/Managing-environments-in-a-distributed-Azure-or-other-cloud-based-NET-solution

+2

Hallo Igorek, können Sie uns bitte einige Code-Beispiele oder Schritt-für-Schritt-Anleitung damit liefern? Ich habe auch Probleme mit web.config in Azure pro Umgebung .... –

+1

+1 für Igorek, um einen Blogpost darüber zu schreiben :) – Slav

+6

Acht Monate später, aber hier ist es: http://www.paraleap.com/ Blog/Post/Managing-Umgebungen in einem verteilten Azure-oder-andere-Cloud-basierte-NET-solution.aspx – Igorek

8

Staging ist ein temporärer verwendet Deployment-Slot vor allem für nicht-Ausfallzeiten Upgrades und die Fähigkeit zu rollen Zurück ein Upgrade.

Es wird empfohlen, Ihr System (entweder in Code oder in Config) nicht mit solchen Azure-spezifischen Merkmalen zu koppeln.

+38

Das ist großartig und gut, außer wenn Ihre Dienste Jobs aus der Warteschlange ziehen und Nebenwirkungen verursachen, bevor Sie VIPs austauschen, es sei denn, Sie haben eine Möglichkeit, ihnen zu sagen, dass sie dies nicht tun sollen. In diesem Fall müssen Sie Ihrem Dienst sagen, dass er solche Dinge erst dann machen soll, wenn er die Produktion erreicht hat. – Jaxidian

+8

Genau, das ist das Problem, das ich habe. Meine Worker-Rolle ruft Ereignisse aus meiner Service-Bus-Warteschlange ab, wenn eine neue Nachricht eintrifft. Ich möchte nicht, dass es sich an die "echte" Produktionswarteschlange anschließt, bis es in die "echte" Produktionsumgebung kommt, also sind Sie nicht die einzige mit diesem Problem. – Michael

+2

Dies war Microsofts Haltung die ganze Zeit, und obwohl ideal und puristisch, funktioniert nicht aus den oben genannten Gründen. Wir modifizieren den cscfg Pre- und Post-VIP-Swap einfach mit einem Wert, der den Slot der Instanz angibt. Einfach, zuverlässig und einfach. – Eric

1

Hier gibt es 4 Punkte

  1. VIP-Swap nur sinnvoll zu prüfen, wenn Sie da die Außenwelt gerichtet ist.AKA, wenn es eine API verfügbar macht und auf Anfragen reagiert.
  2. Wenn Ihr gesamter Dienst Nachrichten aus einer Warteschlange zieht und verarbeitet, sind Ihre Dienste proaktiv und VIP-Swap ist keine gute Lösung für Sie.
  3. Wenn Ihr Service sowohl reaktiv als auch proaktiv ist, möchten Sie vielleicht Ihr Design überdenken. Vielleicht teilen Sie den Dienst in 2 verschiedene Dienste.
  4. Erics Vorschlag, die cscfg-Dateien vor und nach dem VIP-Swap zu ändern, ist gut, wenn der proaktive Teil Ihres Dienstes eine kurze Ausfallzeit benötigt (Da Sie zuerst Staging und Production so konfigurieren, dass keine Nachrichten abgerufen werden, führen Sie VIP Swap aus , und aktualisieren Sie dann die Konfiguration von Production, um mit dem Ziehen von Nachrichten zu beginnen.)
48

Manchmal wünsche ich Leute würden nur die Frage beantworten .. nicht erklären, Ethik oder Best Practices ...

Microsoft ein Codebeispiel tut genau dies hier geschrieben hat: 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

Vielen Dank für die Beantwortung der Frage. –

+2

"Manchmal wünschte ich, die Leute würden nur die Frage beantworten ... nicht erklären, Ethik oder Best Practices ..." - Amen Bruder –

5

Seit Windows Azure Management Libraries und dank @GuaravMantri answer auf eine andere Frage, die Sie es wie folgt tun:

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

Eine einfache Möglichkeit, dieses Problem zu lösen, ist in Ihrer Instanzen eine Einstellschlüssel es, die Umgebung zu identifizieren läuft.

1) In Ihrem Produktionsbereich: Einstellungen Einstellungen >> Anwendungseinstellungen >> App-Einstellungen Und erstellen Sie einen Schlüssel namens SLOT_NAME und Wert "Produktion". WICHTIG: Überprüfen Sie die Slot-Einstellung.

2) Stellen Sie in Ihrem Bereitstellungsslot ein: Legen Sie Einstellungen >> Anwendungseinstellungen >> App-Einstellungen fest Und erstellen Sie einen Schlüssel namens SLOT_NAME und Wert "Staging". WICHTIG: Überprüfen Sie die Slot-Einstellung.

Greifen Sie von Ihrer Anwendung auf die Variable zu und identifizieren Sie, in welcher Umgebung die Anwendung ausgeführt wird. In Java können Sie zugreifen:

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