如何在八达通部署期间优雅地使Web应用程序脱机?

时间:2013-11-17 22:31:39

标签: octopus-deploy

我有点疏忽发现Octopus虽然很棒,但在升级之前关闭你的网络应用并没有做任何可爱或聪明的事。

在我们的解决方案中,我们有两个依赖于相同数据库的网络应用程序(一个网站和一个单独的API网络应用程序),因此当一个正在升级时,另一个仍处于活动状态,并且仍有可能仍然存在Web或API请求在数据库升级时进行维护。

不干净!

清理将是八达通关闭网络应用程序,等到它们关闭然后继续升级,完成后将应用程序池重新联机。

如何实现?

4 个答案:

答案 0 :(得分:16)

自拍回答!

使用Octopus-deploy很容易对部署进行一些额外的处理,您只需要在部署例程中执行一些额外的 Execute-Powershell 步骤。

添加新的第一步以停止应用程序池:

# Settings
#---------------
$appPoolName = "PushpayApi" # Or we could set this from an Octopus environment setting.

# Installation
#---------------
Import-Module WebAdministration     
       # see http://technet.microsoft.com/en-us/library/ee790588.aspx

cd IIS:\


if ( (Get-WebAppPoolState -Name $appPoolName).Value -eq "Stopped" )
{
    Write-Host "AppPool already stopped: " + $appPoolName
}

Write-Host "Shutting down the AppPool: " + $appPoolName
Write-Host (Get-WebAppPoolState $appPoolName).Value

# Signal to stop.
Stop-WebAppPool -Name $appPoolName

do
{
    Write-Host (Get-WebAppPoolState $appPoolName).Value
    Start-Sleep -Seconds 1
}
until ( (Get-WebAppPoolState -Name $appPoolName).Value -eq "Stopped" )
# Wait for the apppool to shut down.

然后在最后添加另一个步骤以重新启动应用程序池:

# Settings
#---------------
$appPoolName = "PushpayApi"

# Installation
#---------------
Import-Module WebAdministration     
       # see http://technet.microsoft.com/en-us/library/ee790588.aspx

cd IIS:\

if ( (Get-WebAppPoolState -Name $appPoolName).Value -eq "Started" )
{
    Write-Host "AppPool already started: " + $appPoolName
}

Write-Host "Starting the AppPool: " + $appPoolName
Write-Host (Get-WebAppPoolState $appPoolName).Value

# To restart the app pool ... 
Start-WebAppPool -Name $appPoolName

Get-WebAppPoolState -Name $appPoolName

答案 1 :(得分:11)

我们采用的方法是在应用程序中部署_app_offline.htm(App Offline)文件。这样我们就可以得到一个很好的消息,解释网站失败的原因。

然后,当部署时,我们使用Mircrosofts Webdeploy将其重命名为app_offline.htm。我们将重命名代码放在PowerShell脚本中,该脚本作为Octopus部署的第一步运行。

write-host "Website: $WebSiteName"

# Take Website Offline
$path = "$WebDeployPath";
$path

$verb = "-verb:sync";
$verb

# Take root Website offline
$src = "-source:contentPath=```"$WebSiteName/_app_offline.htm```"";
$src

$dest = "-dest:contentPath=```"$WebSiteName/app_offline.htm```"";
$dest
Invoke-Expression "&'$path' $verb $src $dest"; 


# Take Sub Website 1 offline
$src = "-source:contentPath=```"$WebSiteName/WebApp1/_app_offline.htm```"";
$dest = "-dest:contentPath=```"$WebSiteName/WebApp1/app_offline.htm```"";
Invoke-Expression "&'$path' $verb $src $dest"; 

$ WebSiteName通常是“默认网站”。另请注意,`不是单引号,而是反引号字符(通常在键盘上的tilda中找到)。

现在,如果章鱼将您的网站部署到新位置,您的网站将自动重新联机。如果您不希望这样,您可以部署具有app_offline文件的新网站。然后,您可以使用以下脚本将其删除。

write-host $WebSiteName

# & "c:\Program Files (x86)\IIS\Microsoft Web Deploy V2\msdeploy.exe" -verb:delete -dest:contentPath="$WebSiteName/app_offline.htm"
# those arn't QUOTES!!!!, they are the back accent thing.  

write-host "Website: $WebSiteName"

# Put Web app Online.
$path = "$WebDeployPath";
$path

$verb = "-verb:delete";
$verb

$dest = "-dest:contentPath=```"$WebSiteName/app_offline.htm```"";
$dest
Invoke-Expression "&'$path' $verb $dest"; 

# Put Sub Website Online
$dest = "-dest:contentPath=```"$WebSiteName/WebApp1/app_offline.htm```"";
Invoke-Expression "&'$path' $verb $dest";

答案 2 :(得分:2)

停止apppool和/或设置App_Offline文件对我来说还不够。两者都没有向客户提供适当的解释,说明网站停机的原因。特别是App_Offline。我需要清理bin文件夹,这会导致YSOD(http://blog.kurtschindler.net/more-app_offline-htm-woes/)。

我的解决方案: 第一个任务将部署的站点重定向到仅包含index.html且具有正确消息的不同文件夹。上一个任务带回原始文件夹。

答案 3 :(得分:0)

更好的解决方案是使用网络负载均衡器,例如f5 LTM。您可以设置多个服务器来接收站点的流量,然后,在部署时,您可以只禁用NLB中的一个节点,以便所有其他流量都转到另一台计算机。

我喜欢f5,因为它非常易编。当我们部署到我们的网站时,我们不会停止任何中断。所有到该站点的流量都只是指向当前未升级的服务器。

有警告:

您必须编写NLM中池成员的downing禁用脚本,以便它可以与您的站点一起使用。如果您的站点需要会话(例如,取决于会话状态或共享对象),则必须从NLB节点中排除流量。在f5中,您可以禁用它们,然后注意连接计数为零(也可编写脚本)。

您必须使用deveopers / dbas强制执行策略,该策略声明所有数据库更改不得导致现有代码中的降级或失败。这意味着您必须非常小心数据库和配置。这样,您甚至可以在开始部署到网站的第一个池之前进行数据库更新。