你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
设置 Azure 应用服务中的过渡环境
将 Web 应用、Linux 上的 Web 应用、移动后端或 API 应用部署到 Azure 应用服务时,如果应用在“标准”、“高级”或“隔离”应用服务计划层中运行,则可以使用单独的部署槽,而不是默认的生产槽。 部署槽是具有自身主机名的实时应用。 两个部署槽(包括生产槽)之间的应用内容与配置元素可以交换。
将应用程序部署到非生产槽具有以下优点:
- 可以在与生产槽交换前,在分阶段部署槽中验证应用更改。
- 首先将应用部署到槽,然后将其交换到生产,这确保槽的所有实例都已准备好,然后交换到生产。 部署应用时,这样可避免停机。 流量重定向是无缝的,且不会因交换操作而删除任何请求。 当不需要预交换验证时,可以通过配置自动交换来自动化这整个工作流。
- 交换后,具有以前分阶段应用的槽现在具有以前的生产应用。 如果交换到生产槽的更改与预期不同,可以立即执行同一交换来收回“上一已知的良好站点”。
每种应用服务计划层支持不同数量的部署槽。 使用部署槽不会产生额外的费用。 若要了解应用层支持的槽数,请参阅应用服务限制。
若要将应用缩放到其他层,请确保目标层支持应用业已使用的槽数。 例如,如果应用有 5 个以上的槽,则不能向下缩放到“标准”层,因为“标准”层只支持 5 个部署槽 。
添加槽
应用必须在“标准”、“高级”或“独立”层中运行,才能启用多个部署槽位 。
在 Azure 门户中搜索并选择“应用服务”,然后选择应用。
在左窗格中,选择“部署槽”>“添加槽” 。
注意
如果应用尚未处于“标准”、“高级”或“独立”层级,则你会收到一条消息,其中指示了支持启用过渡发布的层级 。 此时,可选择“升级”,转到应用的“缩放”选项卡,然后继续。
在“添加槽”对话框中,为槽提供一个名称,并选择是否要从其他部署槽中克隆应用配置。 选择“添加”以继续。
可以从任何现有槽克隆配置。 可以克隆的设置包括应用设置、连接字符串、语言框架版本、Web 套接字、HTTP 版本和平台位数。
注意
目前不会跨槽克隆专用终结点。
添加槽后,选择“关闭”以关闭对话框。 新槽现在显示在“部署槽”页面中。 默认情况下,新槽的“流量 %”设置为 0,所有客户流量都路由到生产槽。
选择新部署槽打开该槽的资源页。
过渡槽具有管理页面,就像任何其他应用服务应用一样。 可以更改此槽的配置。 为了提醒你正在查看的是部署槽,应用名称会显示为“<app-name>/<slot-name>”,应用类型为“应用服务(槽)”。 也可以将槽视为资源组中具有相同名称的单独应用。
选择此槽资源页中的应用 URL。 部署槽有其自己的主机名,同时也是动态应用。 若要限制对部署槽的公共访问权限,请参阅 Azure 应用服务 IP 限制。
即使从其他槽克隆设置,新部署槽位也无内容。 例如,可以使用 Git 发布到此槽。 可以从其他存储库分支或不同的存储库部署到槽。 从 Azure 应用服务获取发布配置文件可以提供部署到槽所需的信息。 可通过 Visual Studio 导入配置文件,以将内容部署到槽。
槽的 URL 格式为 http://sitename-slotname.azurewebsites.net
。 为了使 URL 长度保持在必要的 DNS 限制内,站点名称将会在 40 个字符处被截断,槽名称将会在 19 个字符处被截断,并且将会另外追加 4 个随机字符,以确保生成的域名是独一无二的。
交换期间发生的情况
交换操作步骤
交换两个槽时(通常是从过渡槽交换到生产槽),应用服务将执行以下操作,以确保目标槽不会出现停机:
将目标槽(例如生产槽)中的以下设置应用到源槽的所有实例:
出现其中的任何情况都会触发源槽中所有实例的重启。 在交换并预览期间,这标志着第一阶段结束。 交换操作将会暂停,你可以使用目标槽的设置验证源槽是否正常工作。
等待源槽中的每个实例完成重启。 如果有任何实例无法重启,交换操作将会还原对源槽所做的所有更改,并停止操作。
如果启用了本地缓存,则会通过对每个源槽实例上的应用程序根 ("/") 发出 HTTP 请求,来触发本地缓存初始化。 等到每个实例返回了任何 HTTP 响应。 本地缓存初始化会导致每个实例再次重启。
如果结合自定义预热启用了自动交换,则会通过对每个源槽实例上的应用程序根 ("/") 发出 HTTP 请求,来触发应用程序初始化。
如果未指定
applicationInitialization
,则向每个实例上的源槽的应用程序根触发 HTTP 请求。如果某个实例返回了任何 HTTP 响应,则认为该实例已预热。
如果源槽上的所有实例已成功预热,则通过交换两个槽的路由规则来交换这两个槽。 完成此步骤后,目标槽(例如生产槽)包含先前已在源槽中预热的应用。
源槽包含先前位于目标槽中的预交换应用后,通过应用所有设置并重启实例来执行相同的操作。
在执行交换操作期间的任何时候,初始化已交换应用的所有工作都在源槽上发生。 准备和预热源槽时,目标槽将保持联机,而不管交换是成功还是失败。 若要将过渡槽与生产槽交换,请确保生产槽始终是目标槽。 这样,交换操作才不会影响生产应用。
注意
在交换过程的最后一步中,会快速回收先前生产实例中的实例(即交换操作之后将交换到临时过程的实例)。 如果应用程序中存在任何长期运行的操作,则在辅助角色回收时,这些操作会被放弃。 这同样适用于函数应用。 因此,应采用容错方式编写应用程序代码。
交换哪些设置?
从另一个部署槽克隆配置时,可以编辑克隆的配置。 某些配置元素在交换时遵循内容(不特定于槽),而其他配置元素会在交换之后保留在同一个槽(特定于槽)。 以下列表显示交换槽时会更改的设置。
已交换的设置:
- 常规设置 - 例如 Framework 版本、32/64 位、Web 套接字
- 应用设置(可以配置为停在槽中)
- 连接字符串(可以配置为停在槽中)
- 处理程序映射
- 公用证书
- WebJobs 内容
- 混合连接 *
- 服务终结点 *
- Azure 内容分发网络 *
- 路径映射
标有星号 (*) 的功能计划取消交换。
不交换的设置:
- 发布终结点
- 自定义域名
- 非公共证书和 TLS/SSL 设置
- 缩放设置
- Web 作业计划程序
- IP 限制
- Always On
- 诊断设置
- 跨域资源共享 (CORS)
- 虚拟网络集成
- 托管标识
- 以后缀 _EXTENSION_VERSION 结尾的设置
注意
若要使上述设置可切换,请在应用的每个槽中添加应用设置 WEBSITE_OVERRIDE_PRESERVE_DEFAULT_STICKY_SLOT_SETTINGS
,并将其值设置为 0
或 false
。 这些设置要么全部可交换,要么根本不可交换。 不能仅使某些设置可交换,而使其他设置不可交换。 托管标识从不会进行交换,不受此替代应用设置影响。
应用于不交换的设置的某些应用设置也不交换。 例如,由于诊断设置不会交换,因此相关的应用设置(如 WEBSITE_HTTPLOGGING_RETENTION_DAYS
和 DIAGNOSTICS_AZUREBLOBRETENTIONDAYS
)也不会交换,即使它们未显示为槽设置也是如此。
若要将应用设置或连接字符串配置为粘滞到特定的槽(未交换),请转到该槽的“配置”页。 添加或编辑某个设置,然后选择“部署槽设置”。 选中此复选框可让应用服务知道该设置不可交换。
交换两个槽
可以在应用的“部署槽”页上以及“概述”页上交换部署槽 。 有关交换槽的技术详细信息,请参阅交换期间发生的情况。
重要
将应用从部署槽交换到生产槽之前,请确保生产槽是目标槽,并且已完全根据生产槽中的情况配置了源槽中的所有设置。
若要交换部署槽:
转到应用的“部署槽”页,然后选择“交换”。
“交换”对话框显示将要更改的所选源和目标槽中的设置。
选择所需的“源”和“目标”槽 。 目标通常是生产槽。 此外,选择“源更改”和“目标更改”选项卡,并验证配置更改是否符合预期 。 完成后,可以通过选择“交换”立即交换槽。
若要在交换实际发生之前查看目标槽如何使用新设置运行,请不要选择“交换”,而是按照交换预览中的说明进行操作。
完成后,选择“关闭”以关闭对话框。
如果遇到任何问题,请参阅排查交换问题。
带预览的交换(多阶段交换)
在交换到用作目标槽的生产槽之前,请使用交换的设置验证应用的运行。 源槽在交换完成之前也已预热,这对于任务关键型应用程序是可行的。
在执行交换并预览时,应用服务将执行相同的交换操作,但完成第一个步骤后会暂停。 然后,你可以在完成交换之前验证过渡槽中的结果。
如果取消交换,应用服务会重新将配置元素应用到源槽。
注意
如果其中一个槽已启用站点身份验证,则无法使用预览版交换。
若要交换并预览:
按照交换部署槽中的步骤进行操作,但请选择“使用带预览的交换”。
该对话框显示源槽中的配置在阶段 1 中的更改方式,以及源槽和目标槽在阶段 2 中的更改方式。
如果已准备好开始交换,请选择“开始交换”。
第 1 阶段完成后,对话框中会显示通知。 通过转到
https://<app_name>-<source-slot-name>.azurewebsites.net
来预览源槽中的交换。准备完成挂起的交换后,在“交换操作”中选择“完成交换”,然后选择“完成交换” 。
若要取消挂起的交换,请选择“取消交换”。
完成后,选择“关闭”以关闭对话框。
如果遇到任何问题,请参阅排查交换问题。
若要自动执行多阶段交换,请参阅使用 PowerShell 进行自动化操作。
回滚交换
如果在槽交换后目标槽(例如,生产槽)中发生任何错误,请通过立即交换相同的两个槽以将槽恢复到其交换前状态。
配置自动交换
注意
Linux 上的 Web 应用和用于容器的 Web 应用不支持自动交换。
自动交换简化了 Azure DevOps 方案,在此方案中,可连续部署应用,无需冷启动且不会给应用的客户造成停机。 启用从某个槽到生产槽的自动交换后,每次将代码更改推送到该槽时,应用服务会在源槽中预热后自动将应用交换到生产槽中。
注意
在为生产槽配置自动交换之前,请考虑在非生产目标槽上测试自动交换。
若要配置自动交换:
转到应用的资源页。 选择“部署槽”>“<所需的源槽>”>“配置”>“常规设置”。
对于“启用自动交换”,请选择“打开”。 为“自动交换部署槽”选择所需的目标槽,然后选择在命令栏上“保存”。
执行代码推送到源槽。 片刻之后,自动交换就会发生,而更新将反映在目标槽的 URL 上。
如果遇到任何问题,请参阅排查交换问题。
指定自定义预热
某些应用在交换之前可能需要执行自定义的预热操作。 web.config 中的 applicationInitialization
配置元素可用于指定自定义初始化操作。 交换操作在与目标槽交换之前等待此自定义预热操作完成。 以下是 web.config 片段的示例。
<system.webServer>
<applicationInitialization>
<add initializationPage="/" hostName="[app hostname]" />
<add initializationPage="/Home/About" hostName="[app hostname]" />
</applicationInitialization>
</system.webServer>
有关自定义 applicationInitialization
元素的详细信息,请参阅最常见的部署槽位交换故障以及如何修复它们。
还可以使用以下一项或两项应用设置来自定义预热行为:
WEBSITE_SWAP_WARMUP_PING_PATH
:通过 HTTP 执行 ping 操作来预热站点的路径。 通过指定以斜杠开头的自定义路径作为值来添加此应用设置。 例如/statuscheck
。 默认值为/
。WEBSITE_SWAP_WARMUP_PING_STATUSES
:预热操作的有效 HTTP 响应代码。 使用以逗号分隔的 HTTP 代码列表添加此应用设置。 例如200,202
。 如果返回的状态代码不在列表中,则预热和交换操作会停止。 默认情况下,所有响应代码都是有效的。WEBSITE_WARMUP_PATH
:站点上的一个相对路径,当站点重启时(不仅仅是在槽交换期间)应该对其进行 ping 操作。 示例值包括/statuscheck
或根路径/
。
注意
每次启动应用都需要运行 <applicationInitialization>
配置元素,而两个预热行为应用设置仅适用于槽交换。
如果遇到任何问题,请参阅排查交换问题。
监视交换
如果交换操作需要很长时间才能完成,则可以在活动日志中获取有关交换操作的信息。
在门户的应用资源页上的左窗格中,选择“活动日志”。
交换操作在日志查询中显示为 Swap Web App Slots
。 可以将其展开,然后选择一个子操作或错误来查看详细信息。
路由流量
默认情况下,应用生产 URL (http://<app_name>.azurewebsites.net
) 的所有客户端请求都将路由到生产槽。 可以将部分流量路由到另一个槽。 如果需要用户对新更新的反馈,但是还没有准备好将其发布到生产环境中,那么这个功能非常有用。
自动路由生产流量
若要自动路由生产流量:
转到应用的资源页,然后选择“部署槽”。
在要路由到的槽的“流量 %”列中,指定一个百分比(介于 0 到 100 之间)以表示要路由的总流量。 选择“保存” 。
保存设置后,指定百分比的客户端将随机路由到非生产槽。
客户端在自动路由到特定槽后,会被“固定”到该槽一小时或直到 Cookie 被删除为止。 在客户端浏览器上,可以通过查看 HTTP 标头中的 x-ms-routing-name
cookie 来查看会话固定到哪个槽。 路由到“暂存”槽的请求具有 cookie x-ms-routing-name=staging
。 路由到生产槽的请求具有 cookie x-ms-routing-name=self
。
注意
还可以在 Azure CLI 中使用 az webapp traffic-routing set
命令设置 CI/CD 工具(如 GitHub Actions、DevOps 管道或其他自动化系统)中的路由百分比。
手动路由生产流量
除了自动流量路由以外,应用服务也可以将请求路由到特定槽。 如果想要让用户能够选择加入或退出 beta 应用,这就非常有用。 若要手动路由生产流量,请使用 x-ms-routing-name
查询参数。
例如,若要让用户选择退出 beta 应用,可以在网页中插入以下链接:
<a href="<webappname>.azurewebsites.net/?x-ms-routing-name=self">Go back to production app</a>
字符串 x-ms-routing-name=self
指定生产槽位。 在客户端浏览器访问该链接后,它将重定向到生产槽。 每个后续请求包含一个用于将会话固定到生产槽的 x-ms-routing-name=self
Cookie。
若要让用户选择加入 beta 应用,请将相同的查询参数设置为非生产槽的名称。 下面是一个示例:
<webappname>.azurewebsites.net/?x-ms-routing-name=staging
默认情况下,为新槽提供 0%
的路由规则(以灰色显示)。 将此值显式设置为 0%
时(以黑色文本显示),用户可以使用 x-ms-routing-name
查询参数手动访问过渡槽。 但是,他们不会自动路由到该槽,因为路由百分比设置为 0。 这是一种高级方案,在其中可以对公众“隐藏”过渡槽,同时允许内部团队测试槽中的更改。
删除槽
搜索并选择应用。 选择“部署槽”>“<删除槽>”>“概述”。 应用类型将显示为“应用服务(槽)”,以提醒你正在查看部署槽。 在删除某个槽之前,请确保停止该槽并将该槽中的流量设置为零。 在命令栏上选择“删除”。
使用 PowerShell 进行自动化操作
注意
建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az。
Azure PowerShell 是一个模块,可提供通过 Windows PowerShell 管理 Azure 的 cmdlet,包括对管理 Azure 应用服务的部署槽的支持。
有关安装和配置 Azure PowerShell 的信息以及使用 Azure 订阅对 Azure PowerShell 进行身份验证的信息,请参阅如何安装和配置 Microsoft Azure PowerShell。
创建 Web 应用
New-AzWebApp -ResourceGroupName [resource group name] -Name [app name] -Location [location] -AppServicePlan [app service plan name]
创建槽
New-AzWebAppSlot -ResourceGroupName [resource group name] -Name [app name] -Slot [deployment slot name] -AppServicePlan [app service plan name]
启动带预览的交换(多阶段交换)并将目标槽配置应用到源槽
$ParametersObject = @{targetSlot = "[slot name – e.g. "production"]"}
Invoke-AzResourceAction -ResourceGroupName [resource group name] -ResourceType Microsoft.Web/sites/slots -ResourceName [app name]/[slot name] -Action applySlotConfig -Parameters $ParametersObject -ApiVersion 2015-07-01
取消挂起的交换(带预览的交换)并还原源槽配置
Invoke-AzResourceAction -ResourceGroupName [resource group name] -ResourceType Microsoft.Web/sites/slots -ResourceName [app name]/[slot name] -Action resetSlotConfig -ApiVersion 2015-07-01
交换部署槽
$ParametersObject = @{targetSlot = "[slot name – e.g. "production"]"}
Invoke-AzResourceAction -ResourceGroupName [resource group name] -ResourceType Microsoft.Web/sites/slots -ResourceName [app name]/[slot name] -Action slotsswap -Parameters $ParametersObject -ApiVersion 2015-07-01
在活动日志中监视交换事件
Get-AzLog -ResourceGroup [resource group name] -StartTime 2018-03-07 -Caller SlotSwapJobProcessor
删除槽
Remove-AzResource -ResourceGroupName [resource group name] -ResourceType Microsoft.Web/sites/slots –Name [app name]/[slot name] -ApiVersion 2015-07-01
若要从生产槽执行槽交换,标识需要具有执行 Microsoft.Web/sites/slotsswap/Action
操作所需的(最低)权限。 有关详细信息,请参阅资源提供程序操作
使用资源管理器模板自动执行
Azure 资源管理器模板是用于自动部署和配置 Azure 资源的声明性 JSON 文件。 为了使用资源管理器模板交换槽,你将在 Microsoft.Web/sites/slots 和 Microsoft.Web/sites 资源中设置两个属性:
buildVersion
:这是一个字符串属性,表示槽中部署的应用的当前版本。 例如:“v1”、“1.0.0.1”或“2019-09-20T11:53:25.2887393-07:00”。targetBuildVersion
:这是一个字符串属性,指定槽应使用哪个buildVersion
。 如果 targetBuildVersion 不等于当前的buildVersion
,则此属性会通过查找指定了buildVersion
的槽来触发交换操作。
示例资源管理器模板
以下资源管理器模板将更新过渡槽的 buildVersion
,并在生产槽中设置 targetBuildVersion
。 这会交换两个槽。 该模板假设已使用名为“staging”的槽创建了一个 Web 应用。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"my_site_name": {
"defaultValue": "SwapAPIDemo",
"type": "String"
},
"sites_buildVersion": {
"defaultValue": "v1",
"type": "String"
}
},
"resources": [
{
"type": "Microsoft.Web/sites/slots",
"apiVersion": "2018-02-01",
"name": "[concat(parameters('my_site_name'), '/staging')]",
"location": "East US",
"kind": "app",
"properties": {
"buildVersion": "[parameters('sites_buildVersion')]"
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-02-01",
"name": "[parameters('my_site_name')]",
"location": "East US",
"kind": "app",
"dependsOn": [
"[resourceId('Microsoft.Web/sites/slots', parameters('my_site_name'), 'staging')]"
],
"properties": {
"targetBuildVersion": "[parameters('sites_buildVersion')]"
}
}
]
}
此资源管理器模板是幂等的,这意味着,它可以重复执行,并生成相同的槽状态。 首次执行后,targetBuildVersion
将与当前的 buildVersion
匹配,因此不会触发交换。
使用 CLI 进行自动化
有关用于部署槽的 Azure CLI 命令,请参阅 az webapp deployment slot。
排查交换问题
如果在交换槽的过程中出现任何错误,该错误会记录在 D:\home\LogFiles\eventlog.xml 中。 特定于应用程序的错误日志中也会记录该错误。
下面是一些常见的交换错误:
对应用程序根发出的 HTTP 请求已超时。 交换操作将为每个 HTTP 请求等待 90 秒,并最多重试 5 次。 如果所有重试均超时,则表示交换操作已停止。
如果应用内容超过了为本地缓存指定的本地磁盘配额,本地缓存初始化可能会失败。 有关详细信息,请参阅本地缓存概述。
在自定义预热期间,会在内部发出 HTTP 请求(而不通过外部 URL)。 Web.config 中的某些 URL 重写规则可能会导致这些请求失败。例如,有关重定向域名或强制实施 HTTPS 的规则可能会阻止预热请求访问应用代码。 若要解决此问题,请修改重写规则,在其中添加以下两个条件:
<conditions> <add input="{WARMUP_REQUEST}" pattern="1" negate="true" /> <add input="{REMOTE_ADDR}" pattern="^100?\." negate="true" /> ... </conditions>
即使不执行自定义预热,URL 重写规则也可能仍会阻止 HTTP 请求。 若要解决此问题,请修改重写规则,在其中添加以下条件:
<conditions> <add input="{REMOTE_ADDR}" pattern="^100?\." negate="true" /> ... </conditions>
槽交换之后,应用可能会遇到意外的重启。 这是因为,在交换之后,主机名绑定配置会失去同步,这种情况本身不会导致重启。 但是,某些基础存储事件(例如存储卷故障转移)可能会检测到这些差异,因而强制所有工作进程重启。 为了尽量减少这种重启,请在所有槽中设置
WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG=1
应用设置。 但是,此应用设置不适用于 Windows Communication Foundation (WCF) 应用。