2010-12-01 60 views
45

服务运行时中是否有任何地方会告诉我目前是运行在“分段”还是“生产”?手动修改生产和配置的配置似乎有点麻烦。暂存或生产实例?

回答

75

如果你是在Prod或Staging中,你应该不会改变你的配置。暂存区域并非旨在成为“QA”环境,而是在生产部署之前只有一个控制区域。

当你上传一个新的部署时,你上传你的软件包的当前部署位置被销毁并在上传和启动虚拟机时被关闭10-15分钟。如果您直接上传到生产环境,那就是15分钟的生产停机时间。因此,Staging区域被发明出来:你上传到分段,测试东西,然后点击“Swap”按钮,你的Staging环境神奇地变成了Production(虚拟IP交换)。 因此,你的舞台应该和你的制作完全一样。

我认为你正在寻找的是QA /测试环境?您应该使用自己的Prod/Staging为测试环境打开一项新服务。在这种情况下,您将需要维护多个配置文件集,每个部署环境一套(生产,测试等)

有许多方法可以管理配置 - 发生地狱,特别是Azure具有顶级.config文件,它自己的* .cscfg文件。我更喜欢使用Azure项目执行此操作的方式如下: 设置一个小型Config项目,在那里创建与部署类型相匹配的文件夹。在每个文件夹内安装* .config & * .cscfg文件,这些文件与特定的部署环境相匹配:调试,测试,发布......这些也在Visual Studio中设置为构建目标类型。我有一个小的xcopy命令,它在Config项目的每次编译过程中都会发生,它将Config项目的Build Target文件夹中的所有文件复制到Config项目的根文件夹中。

然后在解决方案中的其他项目中,从Config项目的根文件夹链接到.config或.cscfg文件。

Voila,我的配置自动适应每个构建配置。我还使用.config转换来管理发布与非发布构建目标的调试信息。

如果你读过这一切,仍然希望得到在生产与分期状态在运行时,则: 获取deploymentIdRoleEnvironment.DeploymentId 然后使用管理API以适当X509 certificate获得在Azure structure of your Service和调用GetDeployments方法(这是休息API,但有一个抽象库)。

希望这有助于

编辑:博客帖子的要求有关配置字符串的设置和@http://blog.paraleap.com/blog/post/Managing-environments-in-a-distributed-Azure-or-other-cloud-based-NET-solution

+2

嗨伊格雷克,你能给我们提供一些代码示例或一步一步的指导吗?我也有问题与web.config在Azure每个环境.... – 2011-01-19 11:43:47

+1

+1为伊戈雷克写一篇关于它的博客:) – Slav 2011-02-20 12:58:23

+6

八个月后,但这里是:http://www.paraleap.com/博客/发布/管理分布式环境 - Azure或其他基于云的NET-solution.aspx – Igorek 2011-09-13 02:17:37

8

分级环境之间的切换是主要用于无停机升级和滚动能力的临时部署插槽支持升级。

建议不要将系统(无论是在代码还是在配置中)与此类Azure特性耦合。

1

这里有4分需要考虑的要点

  1. VIP交换才有意义,当你的服务面对外面的世界。AKA,当它暴露一个API并对请求做出反应时。
  2. 如果你所有的服务都是从队列中提取消息并处理它们,那么你的服务是主动的,而且VIP交换对你来说不是一个好的解决方案。
  3. 如果您的服务既具有反应性又具有前瞻性,您可能需要重新考虑您的设计。也许将服务分成2个不同的服务。
  4. 如果您的服务的主动部分可能需要很短的停机时间,那么Eric建议您在VIP交换之前和之后修改cscfg文件是很好的(因为您首先配置暂存和生产不要拉取消息,然后执行VIP交换,然后更新Production的配置以开始拉取消息)。
48

有时候,我希望每个人都能在回答这个问题..不能说明道德或最佳实践...

微软发布了一个代码示例做的正是这样的位置: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(); 
    } 
} 
5

既然Windows Azure Management Libraries并感谢@GuaravMantri answer另外一个问题,你可以做这样的:

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

一个简单的方法来解决这个问题,在您的情况的关键,以确定它运行的环境设置。

1)设置在您的生产插槽上: 设置设置>>应用程序设置>>应用程序设置 然后创建一个名为SLOT_NAME的键和值“production”。重要提示:检查插槽设置。

2)设置您的临时插槽: 设置设置>>应用程序设置>>应用程序设置 然后创建一个名为SLOT_NAME的键并赋值“分段”。重要提示:检查插槽设置。

从应用程序访问变量并确定应用程序正在运行的环境。在Java中,您可以访问:

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