标准答案

  1. 用信号触发根取消,所有下游 goroutine 监听 Done。
  2. HTTP Server.Shutdown 使用带 deadline 的 context 等待在途请求,阻止新连接。
  3. 消费者停止拉取,已处理消息提交进度,未完成消息允许重新投递。
  4. 最后关闭数据库、HTTP client、日志和 metrics,超时则记录并退出。

题目解析

优雅停机应先停止新流量和新任务,再取消根 context,让 HTTP、消费者、定时器和 worker 协作退出。server.Shutdown 只覆盖 HTTP,不会自动停止其他 goroutine。

等待在途任务要有总 deadline。消息位点只能在业务处理完成且可恢复后提交,未完成消息应重新投递;数据库、HTTP client、日志和 metrics 要在业务停止后关闭。

取消后仍可能有 goroutine 试图发送结果或写 channel,因此关闭顺序和 owner 要明确。超时退出要记录未完成任务并依靠启动后的恢复流程。

常见误区

  • 误区:根 context 取消后仍向已关闭 channel 写入。改正:由唯一 owner 关闭,并让发送方同时监听取消。
  • 误区:没有等待 worker 退出。改正:使用 errgroup/WaitGroup 和 shutdown deadline 等待并记录超时。
  • 误区:停机时提交未完成消息位点。改正:只提交已完成且结果可恢复的消息,其他消息留待重投递。

作者信息