让你的 Go 服务优雅的重启 (解决代码发布 Go 服务闪断的问题)

封面

起因

有同学反馈 发布 Go 服务代码 监控报警会出现一堆 5xx 报警

原因

查看生产环境的项目部署脚本 发现目前的部署脚本会

 supervisorctl restart  monkey_interact_service

暴力重启 supervisor 托管的守护进程
会导致 go 的 server 先 stop 停止web服务, 再 start 提供新的 web 服务,
导致上线过程中的请求失败 监控报警群里一吨报警

解决方案

给 Go 进程发送 SIGUSR2 信号 优雅重启 过程中不会中断 web 服务
go web服务可以采用 gracehttp oversee 等成熟的技术方案
github.com/facebookarchive/grace
github.com/jpillora/overseer

验证 — 实践是检验代码的唯一标准

未使用优雅重启前
supervisorctl restart monkey_interact_service
用 wrk 压测 开12 个线程 每秒钟 4000 个请求 请求 20s
有 209456 个成功请求
有 163580 个错误请求

使用优雅重启后
supervisorctl signal SIGUSR2 monkey_interact_service
同样的 使用 wrk 压测 开12 个线程 每秒钟 4000 个请求 请求 20s
223552 个成功请求
0个错误请求

supervisord 版本要求

supervisord >= 3.2.0
由于 supervisord 3.2.0 才增加对 signal 信号的支持
详见 supervisord.org/changes.html#id20

oversee 的原理简析

  1. overseer添加了Fetcher,当Fetcher返回有效的二进位流(io.Reader) 时,主进程会将它保存到临时位置并验证它,替换当前的二进制文件并启动。
    Fetcher运行在一个goroutine中,预先会配置好检查的间隔时间。Fetcher支持File、GitHub、HTTP和S3的方式。详细可查看包package fetcher

  2. overseer添加了一个主进程管理平滑重启。子进程处理连接,能够保持主进程pid不变。

笔者才疏学浅,仓促成文, 如有不当之处,还请大家斧正.

关注微信公众号『代码与远方』,后台回复“1024”查看更多内容,回复“微信”添加我微信。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 1年前 自动加精
讨论数量: 5

在docker 里面也要部署supervisor守护吗?

3年前 评论
CryptoPanda (楼主) 3年前
CryptoPanda (楼主) 3年前
wj2015 3年前

光定时任务服务的话怎么解决呢?

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!