起因
有同学反馈 发布 Go 服务代码 监控报警会出现一堆 5xx 报警
原因
查看生产环境的项目部署脚本 发现目前的部署脚本会
supervisorctl restart monkey_interact_service
暴力重启 supervisor 托管的守护进程
会导致 go 的 server 先 stop 停止web服务, 再 start 提供新的 web 服务,
导致上线过程中的请求失败 监控报警群里一吨报警
解决方案
给 Go 进程发送 SIGUSR2 信号 优雅重启 过程中不会中断 web 服务
go web服务可以采用 gracehttp oversee 等成熟的技术方案
https://github.com/facebookarchive/grace
https://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 信号的支持
详见 http://supervisord.org/changes.html#id20
oversee 的原理简析
-
overseer添加了Fetcher,当Fetcher返回有效的二进位流(io.Reader) 时,主进程会将它保存到临时位置并验证它,替换当前的二进制文件并启动。 Fetcher运行在一个goroutine中,预先会配置好检查的间隔时间。Fetcher支持File、GitHub、HTTP和S3的方式。详细可查看包package fetcher
-
overseer添加了一个主进程管理平滑重启。子进程处理连接,能够保持主进程pid不变。
笔者才疏学浅,仓促成文, 如有不当之处,还请大家斧正.