槽位交换时RunAsync未处理FunctionsHostStoppingError致编排失败
你遇到的编排间歇性失败,是部署槽交换过程中函数主机强制回收触发的已知行为,不是业务代码逻辑错误,具体触发逻辑如下:
- 部署槽交换操作完成后,Azure会对原生产槽上运行的函数主机触发停止回收流程,主机在停止阶段会给所有运行中的函数下发
FunctionsHostStoppingError状态信号,强制终止未执行完的任务。 - 你在App Insights中查不到其他底层异常是正常现象:这个错误是Functions主机层直接抛出的终止信号,不会进入业务代码的执行链路,因此不会留下业务层面的异常日志。
- 默认配置下Durable Functions扩展不会在主机停止时自动等待正在运行的活动、编排任务完成,也不会自动将被中断的活动标记为待重试,而是直接将终止信号包装成未处理异常抛出,最终导致编排失败。
- 如果你使用的Durable Task扩展版本低于2.5.0,还存在已知bug:该版本没有正确处理主机停止的状态信号,会把预期内的优雅终止错误序列化成未处理的
InvalidOperationException抛出,和你看到的异常栈完全匹配。
你抛出的完整异常信息如下:
Orchestrator function 'x' failed: The activity function 'x' failed: "Failed to deserialize exception from TaskActivity: Unhandled exception while executing task: System.InvalidOperationException: RunAsync does not handle the function execution status FunctionsHostStoppingError.
at Microsoft.Azure.WebJobs.Extensions.DurableTask.TaskActivityShim.RunAsync(TaskContext context, String rawInput) in D:\a_work\1\s\src\WebJobs.Extensions.DurableTask\Listener\TaskActivityShim.cs:line 124
at DurableTask.Core.TaskActivityDispatcher.<>c__DisplayClass14_1.<b__2>d.MoveNext() in /_/src/DurableTask.Core/TaskActivityDispatcher.cs:line 183". See the function execution logs for additional details.
按以下顺序调整配置即可解决问题:
- 升级Durable Task扩展到2.5.0以上的稳定版本,修复主机停止状态的异常处理bug。
- 配置函数主机优雅停机参数,在函数应用的应用设置中添加以下配置:
WEBSITE_SHUTDOWN_LIMIT = 300:设置主机停止前最长等待5分钟(可根据你最长的活动执行时长调整,最大支持1800秒),等待正在运行的任务执行完成再回收实例DurableTask:EnableGracefulShutdown = true:开启Durable扩展的优雅停机逻辑,主机收到停止信号后,会将未执行完的活动标记为待重试状态,不会直接抛出失败异常FUNCTIONS_DISABLE_HOST_SHUTDOWN_ON_IDLE_TIMEOUT = true:禁用主机空闲时的自动停机逻辑,避免交换预热阶段主机被意外回收
- 给所有活动函数调用配置瞬时错误重试策略,针对主机终止类的异常自动重试,进一步降低偶发中断的影响。
内容的提问来源于stack exchange,提问作者user989988

