设置 Azure 应用服务中的过渡环境

将 Web 应用、Linux 上的 Web 应用、移动后端和 API 应用部署到 Azure 应用服务时,你可以部署到单独的部署槽而不是默认的生产槽。 如果在应用服务计划的标准层、高级层或独立层中运行,则可以使用此方法。 部署槽是具有自身主机名的实时应用。 两个部署槽位(包括生产槽)之间的应用内容与配置元素可以交换。

将应用程序部署到非生产槽具有以下优点:

  • 在将槽交换到生产环境之前,可以验证应用更改。

  • 在切换到生产环境之前,可以确保槽的所有实例都已预热。 这种方式可以部署应用时避免停机。 流量重定向是无缝的。 由于交换操作,不会删除任何请求。

    当不需要预交换验证时,可以通过配置自动交换来自动化这整个工作流。

  • 交换后,具有以前分阶段应用的槽现在具有以前的生产应用。 如果交换到生产槽的更改与预期不同,可以立即执行同一交换来收回上一已知的良好站点

使用部署槽位不会产生额外的费用。 每种应用服务计划层支持不同数量的部署槽。 若要了解应用层支持的槽数,请参阅 应用服务限制

要将应用缩放到其他层,请确保目标层支持应用业已使用的槽数。 例如,如果应用具有 5 个以上的槽位,则无法将其缩减到标准层。 标准层仅支持五个部署槽位。

以下视频通过说明如何在 Azure 应用服务中设置过渡环境来补充本文中的步骤。

先决条件

  • 执行所需槽操作的权限。 有关所需权限的信息,请参阅 资源提供程序作。 例如,搜索

添加槽

若要启用多个部署槽位,应用必须在标准层、高级层或独立层中运行。

  1. Azure 门户中,转到应用的管理页。

  2. 在左侧窗格中,选择“部署”“部署槽”>。 然后选择“添加”。

    注意

    如果应用尚未位于标准层、高级层或独立层中,请选择“ 升级”。 请先转到应用的缩放选项卡,然后继续下一步。

  3. “添加槽 ”对话框中,为槽命名,并选择是否从另一个部署槽克隆应用配置。 选择“添加”以继续。

    显示用于在门户中配置名为“暂存”的新部署槽位的选择的屏幕截图。

    可以从任何现有槽克隆配置。 可以克隆的设置包括应用设置、连接字符串、语言框架版本、Web 套接字、HTTP 版本和平台位数。

    注意

    目前,专用终结点不能跨槽克隆。

  4. 输入设置后,选择“ 关闭 ”以关闭对话框。 新槽位现在显示在 部署槽位 页上。 默认情况下, 新槽的流量 % 设置为 0 ,所有客户流量都路由到生产槽。

  5. 选择新的部署槽位以打开其资源页。

    显示如何在门户中打开部署槽的管理页的屏幕截图。

    过渡槽具有管理页面,就像任何其他应用服务应用一样。 可以更改此槽的配置。 为了提醒你正在查看部署插槽,应用名称和插槽名称会显示在 URL 中。 应用类型为应用服务(槽)。 也可以将槽视为资源组中具有相同名称的单独应用。

  6. 在插槽的资源页面上,选择应用程序的 URL。 部署槽有其自己的主机名,同时也是动态应用。 若要限制对部署槽的公共访问,请参阅 设置 Azure 应用服务访问限制

即使从其他槽克隆设置,新部署槽位也无内容。 例如,可以使用 Git 发布到此槽。 可以从其他存储库分支或不同的存储库部署到槽。 从 Azure 应用服务获取发布配置文件一文提供了部署到槽所需的信息。 Visual Studio 可以导入该配置文件,以将内容部署到槽。

槽的 URL 格式为 http://sitename-slotname.azurewebsites.net。 为让 URL 长度保持在必要的 DNS 限制范围内,站点名称将截断为 40 个字符。 站点名称和槽名称的字符数加起来必须少于 59 个。

了解交换期间发生的情况

交换操作步骤

交换两个槽时,应用服务将执行以下操作,以确保目标槽不会出现停机:

  1. 将目标槽(例如生产槽)中的以下设置应用到源槽的所有实例:

    在将任何设置应用于源槽时,更改会触发源槽中的所有实例重启。 在交换并预览期间,此操作标志着第一阶段结束。 交换操作已暂停。 你可以使用目标槽的设置验证源槽是否正常工作。

  2. 等待源槽中的每个实例完成重启。 如果有任何实例无法重启,交换操作将会还原对源槽所做的所有更改,并停止操作。

  3. 如果启用了 本地缓存 ,请在源槽的每个实例上向应用程序根(/)发出 HTTP 请求来触发本地缓存初始化。 等到每个实例返回了任何 HTTP 响应。 本地缓存初始化会导致每个实例再次重启。

  4. 如果使用自定义预热启用自动交换,请在源槽的每个实例上触发自定义应用程序初始化

    如果未指定 applicationInitialization,则向每个实例上的源槽的应用程序根触发 HTTP 请求。

    如果某个实例返回了任何 HTTP 响应,则认为该实例已预热。

  5. 如果源槽上的所有实例已成功预热,则通过交换这两个槽的传递规则来交换它们。 完成此步骤后,目标槽(例如生产槽)包含先前已在源槽中预热的应用。

  6. 源槽包含先前位于目标槽中的预交换应用后,通过应用所有设置并重启实例来执行相同的操作。

在交换操作的任何时候,初始化已交换应用的所有工作都在源槽上发生。 准备和预热源槽时,无论交换是成功还是失败,目标槽都将保持联机。 若要将过渡槽与生产槽交换,请确保生产槽始终是目标槽。 这样,交换操作才不会影响生产应用。

注意

以前的生产实例在此交换操作后交换到过渡槽。 这些实例在交换流程的最后一步中回收。 如果应用程序中存在任何长期运行的操作,则在辅助角色回收时,这些操作会被放弃。 此情况同样适用于函数应用。 确保应用程序代码以容错方式编写。

使插槽不可交换的步骤

从另一个部署槽位克隆配置时,可编辑克隆的配置。 某些配置元素在交换时会随内容交换(非特定于槽)。 交换后,其他配置元素会保留在同一个槽中(它们是专属于该槽的)。

交换插槽时,这些设置将被交换:

  • 语言堆栈和版本、32 位和 64 位
  • 应用设置(可以配置为停在槽中)
  • 连接字符串(可以配置为停在槽中)
  • 装载的存储帐户(可配置为坚持某个槽)
  • 处理程序映射
  • 公用证书
  • WebJobs 内容
  • 混合连接(当前)
  • 服务终结点(当前)
  • Azure 内容分发网络(当前)
  • 路径映射

交换槽位时,这些设置不会被交换:

  • 上一列表中未提及的常规设置
  • 发布终结点
  • 自定义域名
  • 非公共证书和 TLS/SSL 设置
  • 缩放设置
  • Web 作业计划程序
  • IP 限制
  • AlwaysOn
  • 诊断设置
  • 跨域资源共享 (CORS)
  • 虚拟网络集成
  • 托管标识和相关设置
  • 以后缀 _EXTENSION_VERSION 结尾的设置
  • 服务连接器创建的设置

注意

若要使设置可交换,请在应用的每个槽中添加应用设置 WEBSITE_OVERRIDE_PRESERVE_DEFAULT_STICKY_SLOT_SETTINGS 。 将其值设置为 0false。 这些设置要么全部可替换,要么全部不可替换。 不能仅使某些设置可交换,而使其他设置不可交换。 托管标识永远不会交换。 此替代应用设置不会影响它们。

应用于不交换的设置的某些应用设置也不交换。 例如,由于诊断设置不会交换,因此相关的应用设置(如 WEBSITE_HTTPLOGGING_RETENTION_DAYSDIAGNOSTICS_AZUREBLOBRETENTIONDAYS)也不会交换,即使它们未显示为槽设置也是如此。

要配置一个应用设置或连接字符串,使其固定在某个不参与交换的特定槽上:

  1. 转到该插槽的 >

  2. 添加或编辑某个设置,然后选择“部署槽位设置”。 选中此复选框会告知应用服务该设置不可交换。

  3. 选择应用

截图显示 Azure 门户中用于将应用程序设置配置为插槽设置的复选框。

交换部署槽

可以在应用的“部署槽”页上以及“概述”页上交换部署槽 。

将应用从部署槽交换到生产槽之前,请确保生产槽是目标槽,并且已完全根据生产槽中的情况配置了源槽中的所有设置。

  1. 转到应用的“部署槽”页,然后选择“交换”。

    显示用于在门户中启动交换操作的选择的屏幕截图。

    “交换”对话框显示将要更改的所选源和目标槽中的设置

  2. 选择所需的“源”和“目标”槽 。 目标通常是生产槽。 此外,选择 “源槽更改 ”和 “目标槽更改 ”选项卡,并验证配置更改是否预期。 完成后,可以通过选择 “开始交换” 立即交换插槽。

    门户中用于配置和完成交换的选择的屏幕截图。

    要在交换发生前查看目标槽在新设置下的运行情况,请不要选择“开始交换”。 请按照本文后面“Swap with preview”中的说明进行操作。

  3. 选择“关闭”以关闭对话框。

如果遇到任何问题,请参阅本文后面的排查交换问题

带预览的交换(多阶段交换)

在交换到用作目标槽的生产槽之前,请使用交换的设置验证应用的运行。 源槽在交换完成之前也已预热,这对于任务关键型应用程序是可行的。

在执行交换并预览时,应用服务将执行相同的交换操作,但完成第一个步骤后会暂停。 然后,你可以在完成交换之前验证过渡槽中的结果。

如果取消交换,应用服务会重新将配置元素应用到源槽。

注意

如果其中一个插槽启用了站点身份验证,则无法使用带预览功能的交换操作。

  1. 按照交换部署槽小节中的步骤进行操作,但请选择“执行交换并预览”

    该对话框显示源槽中的配置在第一阶段如何更改,以及源槽和目标槽在第二阶段的变化方式。

  2. 如果已准备好开始交换,请选择“开始交换”。

    第一阶段完成后,对话框会通知你。

  3. 当您准备好完成未完成的交换时,请在交换操作中选择“完成交换”,然后点击“完成交换”按钮。

    屏幕截图,显示了如何在门户中通过预览配置交换。

    若要取消挂起的交换,请改为选择“ 取消交换 ”,然后选择“ 取消交换 ”按钮。

  4. 完成后,选择“ 关闭 ”以关闭对话框。

如果遇到任何问题,请参阅本文后面的排查交换问题

回滚交换

如果在槽交换后目标槽(例如,生产槽)中发生任何错误,请通过立即交换相同的两个槽以将槽恢复到其交换前状态。

配置自动交换

自动交换简化了 Azure DevOps 方案,在此方案中,可连续部署应用,无需冷启动且不会给应用的客户造成停机。 启用从某个槽到生产槽的自动交换后,每次将代码更改推送到该槽时,应用服务会在源槽中预热后自动将应用交换到生产槽中。

注意

Linux 上的 Web 应用和用于容器的 Web 应用中不支持自动交换。

在为生产插槽配置自动交换之前,请考虑在非生产目标插槽上进行测试。

  1. 转到应用的资源页。 选择 部署>槽位,然后选择所需的源槽。

  2. 在左侧菜单中,选择设置>配置>常规设置

  3. 对于“启用自动交换”,请选择“打开”。 对于“自动交换部署槽”,请选择目标槽。 然后选择命令栏上的 “保存 ”。

    显示门户中用于配置自动交换到生产插槽的选项的屏幕截图。

  4. 运行代码推送到源槽。 一小段时间后会自动交换。 更新反映在目标槽的 URL 上。

如果遇到任何问题,请参阅本文后面的排查交换问题

指定自定义预热

某些应用在交换之前可能需要执行自定义的预热操作。 可以在applicationInitialization中使用Web.config配置元素指定这些自定义动作。 交换操作在与目标槽交换之前等待此自定义预热操作完成。 下面是一个示例 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> 配置元素,而预热行为应用设置仅适用于槽交换。

如果遇到任何问题,请参阅本文后面的排查交换问题

监视交换

如果交换操作需要很长时间才能完成,则可以在活动日志中获取有关交换操作的信息。

  1. 在门户的应用资源页上,在左侧菜单中,选择 “活动日志”。

  2. 交换操作在日志查询中显示为 Swap Web App Slots。 若要查看详细信息,可以展开它并选择其中一个子操作或错误。

自动路由生产流量

默认情况下,对应用生产 URL 的所有客户端请求都路由到生产槽。 可以将部分流量路由到另一个槽。 如果需要新更新的用户反馈,但尚未准备好将其发布到生产环境,此功能非常有用。

  1. 转到 Web 应用的资源页,然后选择 部署>部署插槽

  2. 在要路由到的槽的 流量 % 列中,指定一个百分比(介于 0 到 100 之间),用于表示希望路由的总流量。 然后,选择“保存”。

    显示将请求流量百分比路由到部署槽的门户选择的屏幕截图。

保存设置后,指定的客户端百分比将随机路由到非生产槽。

客户端在自动路由到特定槽后,会被固定到该槽一小时或直到 Cookie 被删除为止。 在客户端浏览器上,可以通过查看 HTTP 标头中的 x-ms-routing-name cookie 来查看会话固定到哪个槽。 路由到“过渡”槽的请求具有 cookie x-ms-routing-name=staging。 路由到生产槽的请求具有 cookie x-ms-routing-name=self

手动路由生产流量

除了自动流量路由以外,应用服务也可以将请求路由到特定槽。 如果想要让用户能够选择加入或退出 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。 此配置是一种高级方案,在其中可以对公众隐藏过渡槽,同时允许内部团队测试槽中的更改。

删除槽

  1. 搜索并选择应用。

  2. 选择“部署”“部署槽”>“要删除的槽”“概述”>>。 应用类型将显示为“应用服务(槽)”,以提醒你正在查看部署槽

  3. 停止槽,并将槽中的流量设置为零。

  4. 在命令栏上,选择“ 删除”。

显示门户中删除部署槽位选项的屏幕截图。

使用资源管理器模板自动执行

Azure 资源管理器模板 是声明性 JSON 文件,用于自动部署和配置 Azure 资源。 若要使用 Resource Manager 模板交换槽位,请对 Microsoft.Web/sites/slots 资源 Microsoft.Web/sites 设置两个属性:

  • buildVersion:字符串属性,表示槽中部署的应用的当前版本。 例如:v11.0.0.12019-09-20T11:53:25.2887393-07:00
  • targetBuildVersion:一个字符串属性,指定槽应具有的值 buildVersion 。 如果 targetBuildVersion 值不等于当前 buildVersion 值,则通过查找具有指定 buildVersion 值的槽来触发交换作。

示例资源管理器模板

以下资源管理器模板通过更新 buildVersion 槽的 staging 值并在生产槽上设置 targetBuildVersion 值来交换两个槽。 必须具有一个名为 staging 的槽。

{
    "$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')]"
            }
        }        
    ]
}

此资源管理器模板是幂等的。 你可以重复运行并生成相同的槽状态。 如果不对模板进行任何更改,同一模板的后续运行不会触发任何槽交换,因为这些槽已处于所需状态。

排查交换问题

如果在 槽交换期间发生任何错误,则错误会显示在 D:\home\LogFiles\eventlog.xml。 特定于应用程序的错误日志中也会记录该错误。

下面是一些常见的交换错误:

  • 对应用程序根发出的 HTTP 请求已超时。 交换操作将为每个 HTTP 请求等待 90 秒,并最多重试 5 次。 如果所有重试均超时,则表示交换操作已停止。

  • 当应用内容超过为本地缓存指定的本地磁盘配额时,本地缓存初始化可能会失败。 有关详细信息,请参阅 Azure 应用服务本地缓存概述

  • 在站点更新操作期间,可能会出现以下错误:“由于槽位的配置设置已准备好进行交换,因此无法更改槽位。” 如果多阶段交换中的第一阶段完成但第二阶段未发生,则会发生此错误。 如果交换失败,也可能发生该错误。 可通过两种方法解决此问题:

    • 取消交换操作,这将使站点重置回旧状态。
    • 完成交换作,将站点更新为所需的新状态。

    若要了解如何取消或完成交换作,请参阅本文前面的 预览版交换(多阶段交换 )。

  • 自定义预热期间,会在内部发出 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) 应用。

下一步