OpenQuality.ru

Качество программного обеспечения

Качество программного обеспечения: в главных ролях

Лента  Радар  Блог  Опыт  
Разум  Видео  Заметки  Эпизоды


Сервисы в Azure: автоматизация развертывания

Добрый день.

Как уже отмечалось ранее, Windows Azure представляет собой облачную операционную систему, реализующую парадигму PaaS: разработчик получает платформу (API) для создания информационных систем и место для их размещения. Практически любая информационная система строится из кирпичиков двух типов: сервис и хранилище данных. Если создание хранилищ в Azure – зачастую однократная операция, то сервисы обновляются постоянно (внесение новой функциональности, исправление багов). Обновлять сервисы в Azure можно через web-интерфейс, но это не всегда удобно. Почему?

Предпосылки для автоматизации и постановка задачи

В Azure большие системы обычно представлены, как минимум, в трех лицах (имена условны): Live (c ней работают пользователи), Test (пространство для тестирования) и Dev (разработка). Далее, более-менее серьезная система состоит из нескольких сервисов, каждый из которых выполняет свою функцию. Например, обработка входного трафика, базовый функционал, web-интерфейс и т.п. И, наконец, в каждом пространстве для сервисов есть слоты Production и Staging – для более удобной отладки и минимизации простоя системы при переходе с одной версии на другую. Каждый сервис представлен, как минимум, двумя файлами: программный код в виде бинарного пакета (*.cspkg) и текстовый конфигурационный файл (*.cscfg). Содержимое конфигурационного файла меняется в зависимости от места разрмещения сервиса и его настроек.

Задача: автоматизировать внесение изменений в конфигурационные файлы и развертывание сервисов в облаке.

Работа с конфигурационными файлами

Конфигурационный файл для сервиса может выглядеть так:

<?xml version="1.0"?>
<ServiceConfiguration serviceName="YourServiceName" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="Controller">
    <Instances count="5" />
    <ConfigurationSettings>
      <Setting name="keepalive" value="true" />
      <Setting name="Storage" value="StorageName:::StorageAccessKey"/>
      <Setting name="Logs" value="LogLocation:::LogAccessKey"/>
    </ConfigurationSettings>
  </Role>
  <Role name="BasicFunctions">
    <Instances count="3" />
    <ConfigurationSettings>
      <Setting name="Connections" value="ConnNumber" />
      <Setting name="Storage" value="StorageName:::StorageAccessKey"/>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

Одни параметры могут оставаться неизменными для любого варианта развертывания, другие параметры меняются при каждом варианте. Для трансформации конфигурационного файла можно воспользоваться XSLT/XPath, передавая входные значения в качестве параметров. Вот пример преобразования:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:sc="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration"
  exclude-result-prefixes="sc"
  version="1.0">
 
  <xsl:param name="Connections" select="'7'"/>
  <xsl:param name="Storage" select="'dfltwthstore:::yARsaf523as5uoaarOY539=='"/>
  <xsl:param name="Logs" select="'dfltlogstore:::R2afFEsrT4eeFT8sWadsUf=='"/>
 
 
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
 
  <xsl:template match="sc:Setting[@name = 'Connections']/@value">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="$Connections"/>
    </xsl:attribute>
  </xsl:template>
 
  <xsl:template match="sc:Setting[@name = 'Storage']/@value">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="$Storage"/>
    </xsl:attribute>
  </xsl:template>
 
  <xsl:template match="sc:Setting[@name = 'Logs']/@value">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="$Logs"/>
    </xsl:attribute>
  </xsl:template>
 
</xsl:stylesheet>

В качестве трансформатора можно воспользоваться утилитой msxsl.exe:

msxsl.exe configurationtemplate.cscfg service.xsl -o configuration.cscfg Connections=8

Если в командной строке заданы параметры (в нашем случае Connections=8), то они переопределяют значения параметров, по умолчанию заданных в xsl-листе.

На выходе получим:

<?xml version="1.0" encoding="UTF-16"?><ServiceConfiguration serviceName="YourServiceName" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="Controller">
    <Instances count="5"></Instances>
    <ConfigurationSettings>
      <Setting name="keepalive" value="true"></Setting>
      <Setting name="Storage" value="dfltwthstore:::yARsaf523as5uoaarOY539=="></Setting>
      <Setting name="Logs" value="dfltlogstore:::R2afFEsrT4eeFT8sWadsUf=="></Setting>
    </ConfigurationSettings>
  </Role>
  <Role name="BasicFunctions">
    <Instances count="3"></Instances>
    <ConfigurationSettings>
      <Setting name="Connections" value="8"></Setting>
      <Setting name="Storage" value="dfltwthstore:::yARsaf523as5uoaarOY539=="></Setting>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

Автоматизация развертывания сервиса

Для решения задачи воспользуемся PowerShell-командлетами, входящими в состав пакета Windows Azure Service Management CmdLets. Перед началом работы нам потребуется создать сертификат и разместить его в облаке (подробности в картинках). После этого нужно подготовить свой скрипт, не забыв задать значения параметров, которые необходимы для его работы. Как и в случае с конфигурационным файлом, меняющиеся параметры нужно передавать из командной строки или зачитывать из конфигурационного файла. Для компактности изложения в примере ниже передаются два параметра (слот и метка), а остальные параметры заданы в теле скрипта.

param([string]$slot, [string]$label)
 
if (!$slot)  { $slot='Staging' }
if (!$label) { $label='NoName' }
 
$cert = Get-Item cert:\CurrentUser\My\0B47A3C9DB926E0D98211C45A1096231EACB57C0
$sub = "9bd4773c-2346-5c34-7a6b-d45b782da12c"
$servicename = 'controller'
$storagename = 'controllerstorage'
$package = "d:\deployment\test\controller\controllerservice.cspkg"
$config = "d:\deployment\test\controller\ServiceConfiguration.cscfg"
 
 
Add-PSSnapin AzureManagementToolsSnapIn
 
Get-HostedService $servicename -Certificate $cert -SubscriptionId $sub |
    Get-Deployment -Slot $slot |
    Set-DeploymentStatus 'Suspended' |
    Get-OperationStatus -WaitToComplete
 
Get-HostedService $servicename -Certificate $cert -SubscriptionId $sub | 
    Get-Deployment -Slot $slot | 
    Remove-Deployment | 
    Get-OperationStatus -WaitToComplete
 
 
New-Deployment -serviceName $servicename -storageserviceName $storagename -subscriptionId $sub -certificate $cert -slot $slot -package $package -configuration $config -label $label |
Get-OperationStatus -WaitToComplete
 
 
Get-HostedService $servicename -Certificate $cert -SubscriptionId $sub | 
    Get-Deployment -Slot $slot | 
    Set-DeploymentStatus 'Running' | 
    Get-OperationStatus -WaitToComplete

Запуск:

powershell .\service.ps1 -slot 'Production' -label '2010-02-15-b'

Что делает скрипт: останавливает сервис, удаляет его, размещает новую версию и запускает сервис. В составе пакета azurecmdlets есть и другие полезные командлеты. Командлеты снабжены подробным описанием.

Собираем воедино

У нас есть кирпичики. Теперь из них можно построить систему. Вот один из вариантов:

1. создается система каталогов. Каталоги первого уровня: пространства развертывания (к примеру, Live, Test, Dev). В каждом из этих каталогов размещаются подкаталоги сервисов (например, Test\Сontroller, Test\BasicFunctions). В этих подкаталогах размещаются соответствующие пакеты сервисов и файлы с конфигурационными параметрами. Например, ночной билд сервиса Сontroller попадает в Dev\Controller для первичной проверки. Или же пакет из Test\BasicFunctions попадает в Live\BasicFunctions после полноценного тестирования.

2. создается скрипт deploy.cmd, который работает так:

deploy.cmd Test    – обновить все сервисы в пространстве Test
deploy.cmd Test Controller BasicFunctions    – обновить cервисы Controller и BasicFunctions в пространстве Test, а остальные сервисы оставить без изменений.

Скрипт deploy.cmd заходит в соответствующие каталоги и для каждого сервиса считывает конфигурационные параметры, выполняет xsl-преобразование и запуск powershell-скрипта.

Безусловно, следует предусмотреть хранение всех выпущенных версий билдов и конфигурационных файлов, а также обработку ошибок. Но это уже совсем другая история. Оставайтесь с нами и зовите друзей. До встречи.

Update: продолжение истории.

Отправить в Twitter, Facebook, ВКонтакте | Опубликовано 15.02.2010 в рубрике "Облака"

Комментарии (2)

  1. Pingback : OpenQuality.ru | Качество программного обеспечения | August 16, 2010

    […] в базовой части приложения, работающего на платформе Windows Azure, проявляется сбой при большом количестве записей в […]


  2. Pingback : OpenQuality.ru | Качество программного обеспечения | September 23, 2010

    […] примере развертывания сервисов в Azure есть серьезный […]



Добавить комментарий

Пожалуйста, исправьте результат: дважды два равно



КРАТКОЕ СОДЕРЖАНИЕ

Что такое качество программного обеспечения и как его улучшить: теория и практика, задачи и решения, подводные камни и обходные пути.


ПУТЕВОДИТЕЛЬ

Проект был основан в 2008 году. За это время часть статей устарела, а некоторые из них вызывают улыбку, но пусть они останутся в том виде, в котором были написаны. Cписок всех статей с краткой аннотацией и разбивкой по рубрикам: открыть.

ПОДПИСКА

Доступ к самым интересным материалам по электропочте и RSS. Подробности.

ИЩЕЙКА