Есть ли где-нибудь в среде выполнения службы, которая сообщит мне, работаю ли я в настоящее время на «Staging» или «Production»? Ручное изменение конфигурации в рабочей среде и обратно кажется немного громоздким.
Промежуточный или производственный экземпляр?
Ответы (6)
Вам действительно не следует изменять свои конфигурации, когда вы основываетесь на том, находитесь ли вы в Prod или Staging. Зона подготовки не предназначена для использования в качестве среды «QA», а только как область ожидания перед развертыванием производства.
Когда вы загружаете новое развертывание, текущий слот развертывания, в который вы загружаете свой пакет, уничтожается и не работает в течение 10-15 минут, пока происходит загрузка и запуск виртуальных машин. Если вы загрузите прямо в рабочую среду, это составит 15 минут производственного простоя. Таким образом, была изобретена промежуточная область: вы загружаете в промежуточную среду, тестируете материал и нажимаете кнопку «Обмен», и ваша промежуточная среда волшебным образом становится производственной (виртуальный обмен IP-адресами). Таким образом, ваша постановка должна быть на 100% такой же, как и ваша постановка.
Я думаю, что вы ищете среду QA/тестирования? Вы должны открыть новую службу для среды тестирования с собственным Prod/Staging. В этом случае вам потребуется поддерживать несколько наборов файлов конфигурации, по одному набору на каждую среду развертывания (производство, тестирование и т. д.).
Существует много способов справиться с конфигурационным адом, особенно в Azure, где помимо файлов .config есть собственные файлы *.cscfg. Я предпочитаю делать это с проектом Azure следующим образом: настройте небольшой проект Config, создайте там папки, соответствующие типам развертывания. Внутри каждой папки устанавливаются наборы файлов *.config и *.cscfg, которые соответствуют конкретной среде развертывания: Debug, Test, Release... они также настраиваются в Visual Studio в качестве целевых типов сборки. У меня есть небольшая команда xcopy, которая возникает во время каждой компиляции проекта Config, которая копирует все файлы из папки Build Target проекта Config в корневую папку проекта Config.
Затем каждый другой проект в решении ССЫЛКИ на файл .config или .cscfg из корневой папки проекта Config.
Вуаля, мои конфиги волшебным образом автоматически адаптируются к каждой конфигурации сборки. Я также использую преобразования .config для управления информацией об отладке для целевых сборок выпусков и не выпусков.
Если вы все это прочитали и все еще хотите получить состояние рабочей и промежуточной версии во время выполнения, выполните следующие действия. Получите deploymentId
от RoleEnvironment.DeploymentId
Затем используйте Management API с правильным X509 certificate
, чтобы получить Azure structure of your Service
и вызвать метод GetDeployments
(это остальные API, но есть библиотека абстракций).
Надеюсь это поможет
Изменить: сообщение в блоге по запросу о настройке строк конфигурации и переключении между средами @ http://blog.paraleap.com/blog/post/Managing-environments-in-a-distributed-Azure-or-другоеоблачноеNET-решение
Иногда мне хочется, чтобы люди просто ответили на вопрос... не объясняли этику или лучшие практики...
Microsoft разместила пример кода, делающего именно это, здесь: https://code.msdn.microsoft.com/windowsazure/CSAzureDeploymentSlot-1ce0e3b5
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();
}
}
Постановка — это временный слот развертывания, используемый в основном для обновлений без простоев и возможности отката обновления.
Не рекомендуется связывать вашу систему (ни в коде, ни в конфигурации) с такими особенностями Azure.
Начиная с библиотек управления Windows Azure и благодаря @GuaravMantri ответ на другой вопрос, вы можете сделать это следующим образом:
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;
}
}
}
Простой способ решить эту проблему — установить для ваших экземпляров ключ, определяющий, в какой среде он работает.
1) Установите в своем производственном слоте: Установите его Настройки >> Настройки приложения >> Настройки приложения И создайте ключ с именем SLOT_NAME и значением «производство». ВАЖНО: проверьте настройку слота.
2) Установите в промежуточном слоте: Установите его Настройки >> Настройки приложения >> Настройки приложения И создайте ключ с именем SLOT_NAME и значением «staging». ВАЖНО: проверьте настройку слота.
Получите доступ к переменной из своего приложения и определите, в какой среде работает приложение. В Java вы можете получить доступ:
String slotName = System.getenv("APPSETTING_SLOT_NAME");
Вот 4 момента, которые следует учитывать
- Обмен VIP имеет смысл только тогда, когда ваш сервис сталкивается с внешним миром. AKA, когда он предоставляет API и реагирует на запросы.
- Если все, что делает ваша служба, это извлекает сообщения из очереди и обрабатывает их, то ваши службы являются упреждающими, и замена VIP не является для вас хорошим решением.
- Если ваш сервис является одновременно реактивным и проактивным, вы можете пересмотреть свой дизайн. Возможно разделить сервис на 2 разных сервиса.
- Предложение Эрика изменить файлы cscfg до и после замены VIP хорошо, если упреждающая часть вашей службы может занять короткое время простоя (поскольку вы сначала настраиваете как промежуточную, так и рабочую среду, чтобы не получать сообщения, затем выполняете замену VIP, а затем обновить конфигурацию Production, чтобы начать получать сообщения).