标准答案
- 信号处理器设置 shutdown 事件,主事件循环或 worker 统一协调退出。
- HTTP server 停止接新连接,消费者停止拉取,已完成消息才提交确认。
- 后台任务有 deadline,超时则保存状态、取消或让消息重新投递。
- 关闭顺序要保留日志和指标冲刷时间,并防止第二次信号无限等待。
题目解析
优雅停机要先改变流量状态,再处理在途工作:停止接收新请求或把实例标记为 not ready,停止消费者拉取,给在途请求和任务一个有限 deadline,最后关闭数据库、HTTP 客户端和日志。每个阶段都必须有剩余时间,不能让最后的清理无限等待。
消息确认代表业务已经完成或结果已经可靠保存。停机时不能为了减少重投递而确认未完成消息;如果任务无法在 deadline 内完成,应让它重新投递或写入可恢复的中间状态,并保证处理逻辑具备幂等性。
Python 的信号处理通常只在主线程接收,事件循环、线程池和子进程需要通过共享的 shutdown 事件协调。第二次终止信号应触发有限的强制退出路径,同时保留足够的日志和指标冲刷时间。
常见误区
- 误区:收到 SIGTERM 后把所有消息立即 ack。改正:只确认已完成且结果已持久化的消息,其他消息让其重投递或恢复。
- 误区:创建后台 Task 后直接退出进程。改正:记录任务引用,在 deadline 内取消、等待并读取异常。
- 误区:先关数据库连接,再等待请求和消费者。改正:先停止新工作并完成在途工作,最后释放它们依赖的资源。