Azure Web App实例切换导致应用线程停止问题咨询
问题背景
我有一个基于.NET 6开发的Blazor应用,通过System.Threading.Timer生成线程,将多租户数据库的数据同步至单个分组数据库。应用运行4-6小时后,线程会无预警停止,且应用端及Web服务器端均未出现任何错误或异常信息。
通过应用内部的线程启停日志及数据库表数据状态,确认线程已停止工作。
我的服务计划为S1,仅配置单实例且未开启自动扩缩容。查看Azure日志后发现,应用在负载状态(未过载)下发生了实例切换,这可能是线程停止的原因,不过从截图来看仍有部分进程处于活跃状态。
相关监控截图
- 实例CPU监控(18:10-18:20左右发生实例切换):

- 对应切换时间的数据库CPU监控(显示线程已停止):

- Azure WebApp日志(明确单实例仍发生实例切换):

技术疑问
- 确实发生了实例切换吗?原因是什么?
- 实例切换会导致线程停止吗?
- 若上述情况属实,能否生成可在多实例或切换期间正常运行的线程?
问题解答
1. 是否发生实例切换及原因
从监控截图和Azure WebApp日志来看,确实发生了实例切换。即使配置单实例,Azure App Service仍可能因以下原因触发实例重建/切换:
- 平台维护:Azure会定期对底层基础设施进行更新、补丁安装,这会回收现有实例并启动新实例。
- 隐性进程异常:即使未捕获到显性错误,若应用进程存在内存泄漏、死锁或未处理的静默异常,Azure健康检测机制可能重启实例。
- 资源阈值触发:即使CPU未过载,内存、磁盘IO或网络连接达到限制阈值时,也可能触发实例回收。
- 配置变更:近期若有应用设置调整、部署槽切换等操作,也会导致实例重启。
2. 实例切换是否会导致线程停止
会的。当Azure触发实例切换时,原实例进程会被强制终止(默认有短时间优雅关闭窗口,但System.Threading.Timer属于后台线程,不会等待其完成)。同步线程依赖原实例进程存在,进程终止后线程自然停止,且由于进程被强制回收,可能不会留下完整异常日志。
3. 如何实现多实例/切换期间正常运行的线程
不能依赖Web应用进程内的后台线程,因为Web应用进程生命周期由Azure管理,随时可能被回收。推荐以下方案:
- Azure Functions(定时触发):将同步逻辑迁移到定时触发的Functions中,由Azure负责调度执行,实例回收后下一次触发会重新执行,还可配置重试策略。
- Azure Logic Apps:通过低代码编排同步流程,内置重试、错误处理机制保证任务可靠性,不受Web应用实例生命周期影响。
- .NET Worker Service:将同步逻辑封装为Worker Service,部署为Azure App Service后台任务、Container Apps或VM,拥有独立进程生命周期,避免Web实例切换的影响。
- 分布式锁+幂等处理:若必须保留在Web应用内,需用Azure Redis Cache实现分布式锁防止多实例重复执行,同时确保同步逻辑幂等(重启后重新执行不导致数据重复/错误);另外用
IHostedService替代System.Threading.Timer,它是.NET官方推荐的后台服务方式,能更好地与应用生命周期集成,在优雅关闭时得到通知。
内容的提问来源于Stack Exchange,提问作者Stavros Koureas
相关产品推荐
相关产品推荐

