Visual StudioでゼロダウンタイムでIISにWebアプリケーションを配備する
17854 ワード
導入
以前は、Visual StudioからWebアプリケーションをWeb展開ツールを使用してIISに展開する方法について書きました.あなたが気づいたかもしれない1つの問題は、展開の間に起こるダウンタイムです.
それで、このポストで、私は使用方法について書きますBlue-Green Deployment ゼロダウンタイム展開を達成するためのIISで
アプリケーション要求ルーティング(ARR)をインストールするために、少なくともIIS 7を必要とします.
目次
基本理念
We will create two server, blue and green. One of them will be accessible through public network for our clients, and the other only through the private network for testing purposes.
Deployment is done in these steps:
- We will deploy our new web app to the private network server.
- Make sure it is working as intended.
- Make the private network server accessible to public network, now both servers can receive clients requests.
- Gracefully shutdown the original public network server; now it can't receive new requests but will finish its current requests.
- Make the original public network server accessible only to private network, then turn it on.
- Now the green and blue servers are switched, and in each deployment they will get switched again.
ステップ
1 . Webプラットフォームインストーラのダウンロードとインストール
それは直接ツールをダウンロードする代わりにWebPIを使用することをお勧めしますWebPIも依存関係を取得し、現在のシステム設定に応じてこれらのツールを設定します.
Web Platform Installer
2 .アプリケーションリクエストルーティング( ARR )を取得する
青と緑のサーバを作る
つのウェブサイト、クライアントの要求を受信するポート80のいずれかを、我々はそれをサーバーファームと呼ぶでしょう.他の2つのポートは、8001と8002といって、この例ではそれぞれ青と緑と呼ばれます.
つのウェブサイトには
content.html
どちらがblue
or green
その中に書かれている.また、これらのウェブサイトをホストファイルに追加し、localhostを指すようにします.
Windowsでは、ホストファイルは次のとおりです.
C:\Windows\System32\drivers\etc\hosts
テストしましょう.
サーバーファームの設定
クリエイトserver farm , そして、我々はちょうど青と緑のウェブサイトに割り当てられたポート番号でそれに2つのサーバーを追加します.
再起動規則を追加するプロンプトを取得します.我々は、後で我々自身の書き換え規則を加えます.
これは次のようになります.
健康診断の構成
ヘルステストはどのサーバーがクライアントリクエストを受け取るかを決めるでしょう.
最初にHTMLファイルを作成する
is-up.html
ウェブサイトの横でcontent.html
ファイル.そのうちの一つが含まれます1
, その他0
.テストしましょう.
当社のサーバーファームに移動し、健康テストを構成します
is-up.html
ファイル.検証する.
サーバーファームで監視と管理をチェックします.
問題ログ
Health Testは毎秒ごとに各サーバに要求をします、そして、これらの要求は記録されます.
この問題を解決するためには、
is-up.html
ログファイルからapplicationHost.config
IISのファイル.私が知っている限りでは、これはIISマネージャを通して可能ではありません.Windowsでは
applicationHost.config
ファイルは次の場所にあります.C:\Windows\System32\inetsrv\config\applicationHost.config
このコードをapplicationHost.config
ファイル. <location path="blue/is-up.html">
<system.webServer>
<httpLogging dontLog="true" />
</system.webServer>
</location>
<location path="green/is-up.html">
<system.webServer>
<httpLogging dontLog="true" />
</system.webServer>
</location>
このようにしてapplicationHost.config
ファイルは次のようになります.URL書き換え規則の追加
URL Rewrite は、指定した規則に従ってリクエストURLを変更するために使用されます.
我々はサーバーファームへのルート要求にこのモジュールを使用します.
WebPIを使用してARRをインストールした場合、URLの書き換えもインストールされます.
IIS ManagerのメインノードからURLの書き換えを選択し、空白のルールを追加します.
パターンはURLにマッチします:
.*
ポートの条件を追加する
80
アクションタイプは次のとおりです.サーバーファームへのルート
最後に、以下のようになります.
テストしましょう.
我々が変わるならば
0
and 1
にis-up.html
ファイル現在、thigsが設定されます.次に、展開プロセスを自動化するスクリプトを書きます.
スクリプト
We can use PowerShell to automate some processes.
サーバーファームオブジェクトを取得する
function get-webfarm {
param($webFarmName)
$assembly = [System.Reflection.Assembly]::LoadFrom("$env:systemroot\system32\inetsrv\Microsoft.Web.Administration.dll")
$mgr = new-object Microsoft.Web.Administration.ServerManager "$env:systemroot\system32\inetsrv\config\applicationhost.config"
$conf = $mgr.GetApplicationHostConfiguration()
$section = $conf.GetSection("webFarms")
$webFarms = $section.GetCollection()
$webFarms | Where {
$_.GetAttributeValue("name") -eq $webFarmName
}
}
サーバーが不健全であるか確認するには
$webFarmName = "server-farm"
$webFarm = get-webfarm $webFarmName
$unhealthyServer = $webFarm.GetCollection() | where {
!$_.GetChildElement("applicationRequestRouting").GetChildElement("counters").GetAttributeValue("isHealthy")
}
$unhealthyServer.GetAttributeValue("address")
スイッチブルーとグリーン
$webFarmName = "server-farm"
$addressBlue = "blue"
$addressGreen = "green"
$siteBlue = "http://blue:8001/"
$siteGreen = "http://green:8002/"
$pathBlue = "C:\inetpub\sites\blue"
$pathGreen = "C:\inetpub\sites\green"
$warmUpRequestURL = "content.html"
$healthCheckFileName = "is-up.html"
$healthyResponse = "1"
$unhealthyResponse = "0"
$webFarm = get-webfarm $webFarmName
# Get health check interval
$healthCheckTimeoutS = $webFarm.GetChildElement("applicationRequestRouting").GetChildElement("healthCheck").GetAttributeValue("interval").TotalSeconds
$healthyServer = $webFarm.GetCollection() | where {
$_.GetChildElement("applicationRequestRouting").GetChildElement("counters").GetAttributeValue("isHealthy")
}
$siteToWarm = $siteBlue
$serverAddressToBringDown = $addressGreen
$pathToBringDown = $pathGreen
$pathToBringUp = $pathBlue
if($healthyServer.GetAttributeValue("address") -eq $addressBlue) {
$siteToWarm = $siteGreen
$serverAddressToBringDown = $addressBlue
$pathToBringUp = $pathGreen
$pathToBringDown = $pathBlue
}
# Initializing unhealthy server, and making sure it works as intended
Write-Host "Warming up $($siteToWarm)"
Do {
$time = Measure-Command {
$res = Invoke-WebRequest "$($siteToWarm)$($warmUpRequestURL)"
}
$ms = $time.TotalMilliSeconds
If ($ms -ge 400) {
Write-Host "$($res.StatusCode) from $($siteToWarm) in $($ms)ms"
}
} While ($ms -ge 400)
Write-Host "$($res.StatusCode) from $($siteToWarm) in $($ms)ms"
# If the unhealthy server is fine, start the switching operation
if ($res.StatusCode -eq 200) {
Write-Host "Bringing $($pathToBringUp) up"
(Get-Content $pathToBringUp\$healthCheckFileName).replace($unhealthyResponse, $healthyResponse) | Set-Content $pathToBringUp\$healthCheckFileName
# Wait for health check to mark the server healthy, afterwards we can bring down the other server
Write-Host "Waiting for health check to pass in $($healthCheckTimeoutS) seconds..."
Start-Sleep -s $healthCheckTimeoutS
Write-Host "Draining $($pathToBringDown)"
$serverToBringDown = $webFarm.GetCollection() | Where {
$_.GetAttributeValue("address") -eq $serverAddressToBringDown
}
$arrToBringDown = $serverToBringDown.GetChildElement("applicationRequestRouting")
$method = $arrToBringDown.Methods["SetState"]
$methodInstance = $method.CreateInstance()
# 0 = Available
# 1 = Drain
# 2 = Unavailable
# 3 = Unavailable Gracefully
$methodInstance.Input.Attributes[0].Value = 1
$methodInstance.Execute()
# loop till there is no requests, then bring the server down
$currentRequests = $arrToBringDown.GetChildElement("counters").GetAttributeValue("currentRequests")
While($currentRequests -gt 0) {
Start-Sleep -s 1
$currentRequests = $arrToBringDown.GetChildElement("counters").GetAttributeValue("currentRequests")
}
Write-Host "Bringing $($pathToBringDown) down"
(Get-Content $pathToBringDown\$healthCheckFileName).replace($healthyResponse, $unhealthyResponse) | Set-Content $pathToBringDown\$healthCheckFileName
$methodInstance.Input.Attributes[0].Value = 0
$methodInstance.Execute()
} else {
Write-Host "Cannot warm up $($siteToWarm)"
}
リモートアクセス
To run these scripts remotely, we will use Windows Remote Management (WinRM) .WinRMを設定するには、次の手順に従います.
5985
ネットワークを通して開いています.winrm qc
リモートサーバーでy
を返します.winrm set winrm/config/client '@{TrustedHosts="your.server.IP"}'
ローカル.Invoke-Command -ComputerName your.server.ip -ScriptBlock {
$webFarmName = "server-farm"
$assembly = [System.Reflection.Assembly]::LoadFrom("$env:systemroot\system32\inetsrv\Microsoft.Web.Administration.dll")
$mgr = new-object Microsoft.Web.Administration.ServerManager "$env:systemroot\system32\inetsrv\config\applicationhost.config"
$conf = $mgr.GetApplicationHostConfiguration()
$section = $conf.GetSection("webFarms")
$webFarms = $section.GetCollection()
$webFarm = $webFarms | Where {
$_.GetAttributeValue("name") -eq $webFarmName
}
$unhealthyServer = $webFarm.GetCollection() | where {
!$_.GetChildElement("applicationRequestRouting").GetChildElement("counters").GetAttributeValue("isHealthy")
}
$unhealthyServer.GetAttributeValue("address")
} -Credential (New-Object System.Management.Automation.PSCredential ("user", (ConvertTo-SecureString 'password' -AsPlainText -Force)))
これは単純な認証ですlink .Visual Studioとの統合
This builds on my previous .
We will use Targets MSBuildで、どのサーバーを配備するかを制御し、配備後に青と緑のサーバーを切り替える.プロジェクトディレクトリにPowerShellスクリプトを追加します
\Properties\Scripts\
発行プロファイルで、これらのコード行をプロジェクトタグに追加します.<Target Name="DetermineUnhealthy" BeforeTargets="BeforePublish">
<Exec Command="powershell -executionpolicy unrestricted "& ""$(MSBuildProjectDirectory)\Properties\Scripts\GetUnhealthy.ps1""""
ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="DeployIisAppPath"/>
</Exec>
</Target>
このコードは、展開の開始前に不健康なサーバーを決定し、DeployIisAppPath
プロパティ.IISのサイト下のアプリケーションの場合:
<Target Name="DetermineUnhealthy" BeforeTargets="BeforePublish">
<Exec Command="powershell -executionpolicy unrestricted "& ""$(MSBuildProjectDirectory)\Properties\Scripts\GetUnhealthy.ps1""""
ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="UnhealthySite"/>
</Exec>
<CreateProperty Value="$(UnhealthySite)/AppName">
<Output TaskParameter="Value" PropertyName="DeployIisAppPath"/>
</CreateProperty>
</Target>
配備後に直接切り替えたい場合は、次のコードを追加します.<Target Name="SwitchBlueGreen" AfterTargets="AfterPublish">
<Exec Command="powershell -executionpolicy unrestricted "& ""$(MSBuildProjectDirectory)\Properties\Scripts\SwitchBlueGreen.ps1"""" />
</Target>
私の場合、2つのプロファイルがあります.これで、ゼロダウンタイムでIISに展開できます.
参考
私がここで書いたもののほとんどを私に教えました.
Reference
この問題について(Visual StudioでゼロダウンタイムでIISにWebアプリケーションを配備する), 我々は、より多くの情報をここで見つけました https://dev.to/mark0960/deploy-web-app-to-iis-with-zero-downtime-in-visual-studio-3f5kテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol