Статьи

Уменьшите масштаб до облака, уменьшите масштаб до стойки

Это плохое название поста в блоге, правда! Если Стив и Райан разместят этот пост в « Обложке облака», я готов поспорить, что они посмеются над названием. Так или иначе…

Представьте, что у вас есть приложение, работающее в вашем собственном центре данных. Все работает гладко, за исключением некоторых скачков мощности время от времени. Кто-то попросил вас сделать что-то с этим с низким бюджетом. Недостаточно бюджета для нового оборудования, и откровенно новое оборудование было бы просто смешно, если просто обеспечить пропускную способность на несколько часов каждый месяц.

Возможное решение: миграция приложения в облако во время скачков емкости. Не всегда, хотя: аппаратное обеспечение находится в доме, и вы можете быть хакером, который хочет видеть мигающие огни LAN и HDD большую часть времени. Я должен признать: мигающие огни это круто! Но я отвлекся.

Разве не было бы здорово иметь скрипт Powershell, который можно запускать при возникновении всплеска? Этот скрипт переместит все в Windows Azure. Также должен существовать другой сценарий, перенося все назад, когда острие остынет. Да, вы слышите, как я иду: вот о чем этот пост в блоге.

Для тех, кто не может ждать, вот загрузка: ScaleOutToTheCloud.zip (2.81 кб)

Математический обзор

Поскольку каждая классная идея сочетается с причудливыми картинками, вот схематический обзор того, что может произойти, когда вы прочитаете этот пост до конца. Прежде всего: у вас есть группа пользователей, которые используют ваше приложение. Как хороший администратор, вы развернули маршрутизацию запросов приложений IIS в качестве балансировщика нагрузки / обратного прокси-сервера перед сервером приложений. Все довольны!

К сожалению: иногда слишком много пользователей. Они продолжают использовать приложение, и сервер приложений загорается.

Настало время что-то сделать. В самом деле. Пользователи получают тайм-ауты и все неприятные сообщения об ошибках. Почему бы не запустить скрипт Powershell, который упаковывает все локальное приложение для WIndows Azure и развертывает приложение?

 

После развертывания и после запуска приложения в Windows Azure для этого же сценария остается одно: изменить ARR и перенаправить весь трафик в Windows Azure вместо этого умирающего сервера.

 

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

Давайте попробуем сделать это с помощью Powershell …

Скрипт Powershell

Скрипт Powershell будет грубо выполнять 5 задач:

  • Загрузить настройки
  • Загрузить зависимости
  • Создайте список файлов для развертывания
  • Упакуйте эти файлы и разверните их
  • Обновление серверов маршрутизации запросов приложений IIS

Хотите скачать? Вот и все: ScaleOutToTheCloud.zip (2.81 кб)

Загрузить настройки

Для этого сценария в игре достаточно параметров. Я нашел их в файле settings.ps1, который выглядит так:

# Settings (prod)
$global:wwwroot = "C:\inetpub\web.local\"
$global:deployProduction = 1
$global:deployDevFabric = 0
$global:webFarmIndex = 0
$global:localUrl = "web.local"
$global:localPort = 80
$global:azureUrl = "scaleout-prod.cloudapp.net"
$global:azurePort = 80
$global:azureDeployedSite = "http://" + $azureUrl + ":" + $azurePort
$global:numberOfInstances = 1
$global:subscriptionId = ""
$global:certificate = "C:\Users\Maarten\Desktop\cert.cer"
$global:serviceName = "scaleout-prod"
$global:storageServiceName = ""
$global:slot = "Production"
$global:label = Date

Давайте объясним это …

$ Глобальный: Wwwroot Путь к файлу к локальному приложению.
$ Глобальный: deployProduction Развернуть в Windows Azure?
$ Глобальный: deployDevFabric Развернуть в разработке ткань?
$ Глобальный: webFarmIndex Индекс 0 вашего веб-фермы. Посмотрите в диспетчере IIS и отметьте порядок вашей веб-фермы в списке веб-фермы.
$ Глобальный: localUrl Локальный URL-адрес, зарегистрированный в ARR в качестве сервера приложений.
$ Глобальный: локальный_порт Локальный порт, зарегистрированный в ARR в качестве сервера приложений.
$ Глобальный: azureUrl URL-адрес Windows Azure, который будет зарегистрирован в ARR в качестве сервера приложений.
$ Глобальный: azurePort Порт Windows Azure, который будет зарегистрирован в ARR в качестве сервера приложений.
$ Глобальный: azureDeployedSite Окончательный URL-адрес развернутого приложения Windows Azre.
$ Глобальный: numberOfInstances Количество экземпляров для запуска в Windows Azure.
$ Глобальный: SubscriptionId Ваш идентификатор подписки Windows Azure.
$ Глобальный: сертификат Ваш сертификат для управления Windows Azure.
$ Глобальный: SERVICENAME Ваше имя службы Windows Azure.
$ Глобальный: storageServiceName Учетная запись хранения Windows Azure, которая будет использоваться для загрузки упакованного приложения.
$ Глобальный: слот Слот для развертывания Windows Azure (производство / подготовка)
$ Глобальные: этикетки Метка для развертывания. Я выбрал текущую дату и время.

Загрузить зависимости

Далее наш скрипт загрузит зависимости. Существует еще один набор CmdLets, который вам нужно установить: CmdLets для управления Windows Azure, доступный по адресу http://code.msdn.microsoft.com/azurecmdlets .

Вот набор, который мы загружаем:

# Load required CmdLets and assemblies
$env:Path = $env:Path + "; c:\Program Files\Windows Azure SDK\v1.2\bin\"
Add-PSSnapin AzureManagementToolsSnapIn
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")

Создайте список файлов для развертывания

Чтобы упаковать приложение, нам нужен текстовый файл, содержащий все файлы, которые должны быть упакованы и развернуты в Windows Azure. Это делается путем рекурсивного обхода каталога, в котором размещается локальное приложение.

$filesToDeploy = Get-ChildItem $wwwroot -recurse | where {$_.extension -match "\..*"}
foreach ($fileToDeploy in $filesToDeploy) {
$inputPath = $fileToDeploy.FullName
$outputPath = $fileToDeploy.FullName.Replace($wwwroot,"")
$inputPath + ";" + $outputPath | Out-File FilesToDeploy.txt -Append
}

Упакуйте эти файлы и разверните их

Я был вежлив и включил это как для разработки, так и для Windows Azure. Вот код упаковки и развертывания для структуры разработки:

# Package & run the website for Windows Azure (dev fabric)
if ($deployDevFabric -eq 1) {
trap [Exception] {
del -Recurse ScaleOutService
continue
}
cspack ServiceDefinition.csdef /roleFiles:"WebRole;FilesToDeploy.txt" /copyOnly /out:ScaleOutService /generateConfigurationFile:ServiceConfiguration.cscfg

# Set instance count
(Get-Content ServiceConfiguration.cscfg) |
Foreach-Object {$_.Replace("count=""1""","count=""" + $numberOfInstances + """")} |
Set-Content ServiceConfiguration.cscfg

# Run!
csrun ScaleOutService ServiceConfiguration.cscfg /launchBrowser
}

 И то же самое для ткани Windows Azure:

# Package the website for Windows Azure (production)
if ($deployProduction -eq 1) {
cspack ServiceDefinition.csdef /roleFiles:"WebRole;FilesToDeploy.txt" /out:"ScaleOutService.cspkg" /generateConfigurationFile:ServiceConfiguration.cscfg

# Set instance count
(Get-Content ServiceConfiguration.cscfg) |
Foreach-Object {$_.Replace("count=""1""","count=""" + $numberOfInstances + """")} |
Set-Content ServiceConfiguration.cscfg

# Run! (may take up to 15 minutes!)
New-Deployment -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot -StorageServiceName $storageServiceName -Package "ScaleOutService.cspkg" -Configuration "ServiceConfiguration.cscfg" -label $label
$deployment = Get-Deployment -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot
do {
Start-Sleep -s 10
$deployment = Get-Deployment -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot
} while ($deployment.Status -ne "Suspended")

Set-DeploymentStatus -Status "Running" -SubscriptionId $subscriptionId -certificate $certificate -ServiceName $serviceName -Slot $slot
$wc = new-object system.net.webclient
$html = ""
do {
Start-Sleep -s 60
trap [Exception] {
continue
}
$html = $wc.DownloadString($azureDeployedSite)
} while (!$html.ToLower().Contains("<html"))
}

Обновление серверов маршрутизации запросов приложений IIS

Это можно сделать, злоупотребив классом .NET Microsoft.Web.Administration.ServerManager .

# Modify IIS ARR
$mgr = new-object Microsoft.Web.Administration.ServerManager
$conf = $mgr.GetApplicationHostConfiguration()
$section = $conf.GetSection("webFarms")
$webFarms = $section.GetCollection()
$webFarm = $webFarms[$webFarmIndex]
$servers = $webFarm.GetCollection()
$server = $servers[0]
$server.SetAttributeValue("address", $azureUrl)
$server.ChildElements["applicationRequestRouting"].SetAttributeValue("httpPort", $azurePort)
$mgr.CommitChanges()

 

Запуск сценария

Конечно, я проверил это, чтобы увидеть, работает ли это. И угадайте, что: это делает!

Сам вывод скрипта не очень интересен. Я не добавил журналы или значимые сообщения, чтобы посмотреть, что он делает. Вместо этого вы просто увидите, как это работает.

 

После запуска портал Windows Azure вскоре покажет, что приложение действительно развертывается. Без рук!

После обычных 15-20 минут, которые требуются для первого запуска развертывания и приложения, IIS ARR переконфигурируется Powershell.

 

А мои локальные пользователи могут просто просматривать http: //farm.local, который теперь просто перенаправляет запросы в Windows Azure. Не обманывайте себя: я просто упаковал веб-сайт IIS по умолчанию и развернул его в Windows Azure. Очень производительный!

 

Вывод

Оно работает! И это модно и круто. Я думаю, что в некоторых ситуациях это может быть хорошей моделью развертывания и масштабирования, однако на локальном сервере ARR все еще может быть узкое место: если на этом сервере слишком много трафика, новый сервер записи работает. , Обратите внимание, что это решение будет работать для любого веб-сайта, размещенного на IIS: пользовательских приложений ASP.NET, ASP.NET MVC, PHP,…

Вот загрузка: ScaleOutToTheCloud.zip (2.81 КБ)