Go 服务优雅重启
很多时候对于服务升级的做法简单粗暴, 就简单的杀进程启动新的进程.
还有的好一点就是多个相同的服务依次升级, 保证有服务可用. 但是公平的说这两种都会丢失请求中的连接. 鉴于这种情况, 在现实中我们可以使用优雅重启来搞定这个问题. Golang 实现优雅重启的原理也很简单:
监听 USR2 信号;
收到信号后将服务监听的文件描述符传递给新的子进程;
此时新老进程同时接收请求;
父进程停止接收新请求, 等待旧请求完成(或超时);
父进程退出.
对于上面的原理看似简单, 其实是分成了两个大的要点:
新老进程同时监听同一端口, 这个很简单, Go 很早就支持;
如何等待旧的请求完成, 这个在 Go 1.8 (新增了Server.Shutdown) 之前是需要费一番功夫的.
我们搞定了上面的原理之后, 加上 Go 1.8 的完美等待旧请求的实现, 我实现了一个简单的优雅重启库: https://github.com/douglarek/zerodown.
zerodown 完美兼容基于 Go 标准库 Server 监听服务. 对于标准库的使用, 我们可以象下面一样使用:
package main |
对于第三方库 Gin 我们可以:
package main |