在服务端程序更新或重启时,如果我们直接 kill -9
杀掉旧进程并启动新进程,会有以下几个问题:
- 旧的请求未处理完,如果服务端进程直接退出,会造成客户端链接中断(收到
RST
) - 新请求打过来,服务还没重启完毕,造成
connection refused
- 即使是要退出程序,直接
kill -9
仍然会让正在处理的请求中断
很直接的感受就是:在重启过程中,会有一段时间不能给用户提供正常服务;同时粗鲁关闭服务,也可能会对业务依赖的数据库等状态服务造成污染。
所以我们服务重启或者是重新发布过程中,要做到新旧服务无缝切换,同时可以保障变更服务 零宕机时间!
作为一个微服务框架,那 go-zero
是怎么帮开发者做到优雅退出的呢?下面我们一起看看。
优雅退出
在实现优雅重启之前首先需要解决的一个问题是 如何优雅退出:
> 对 http 服务来说,一般的思路就是关闭对 fd
的 listen
, 确保不会有新的请求进来的情况下处理完已经进入的请求, 然后退出。
go 原生中 http
中提供了 server.ShutDown()
,先来看看它是怎么实现的:
- 设置
inShutdown
标志 - 关闭
listeners
保证不会有新请求进来 - 等待所有活跃链接变成空闲状态
- 退出函数,结束