欢迎访问我的博客,你的支持,是我最大的动力!

Go程序的优雅重启机制

Linux 马从东 41℃ 评论

参考文章:
英文原文
无停机优雅重启Go程序

在不停机的情况下,替换二进制文件或修改配置

两种可行的方案:

方案一
在套接字上设置 SO_REUSEPORT 从而让多个进程能被绑定到同一个端口上,此时有多个接受队列向多个进程提供数据
现状:由于有多个接受队列,偶有丢弃挂起的TCP连接;Go对设置该属性支持不够好,需要借助第三方包,如
https://github.com/libp2p/go-reuseport

方案二
复制套接字,并将其以文件的形式传送给一个子进程,然后在新的进程中重新创建这个套接字,此时有一个接受队列向多个进程提供数据
os/exec实际不赞同这种用法,出于安全考虑,只传递stdin、stdout、stderr给子进程
但os包确实提供较低级原语,用于将文件传递给子进程

使用SIGUSR2信号,当进程接收到该信号后,复制监听套接字,然后创建一个新的进程,同时将监听套接字以文件形式和这个套接字的元数据以环境变量形式传入子进程,子进程开始运行后,会依据传进来的文件和元数据重建套按字,并开始处理流量
当一个套接字被复制时,入栈流量会在两个套接字之间以轮询方式进行负载。即在替换的过程中,两个进程都会接受新的连接
父进程接受到SIGQUIT信号后,开始关闭进程,停止接受新的连接,待所有现有连接断开或超时,然后会关闭监听套接字并退出

下面为示例代码(对原文代码进行了注解和修整)

测试方法:

./gracedown &
curl http://localhost:8080
kill -SIGUSR2 1234
curl http://localhost:8080
curl http://localhost:8080

lsof -i :8080 -P
# 在发送完SIGUSR2信号后  可以看到 两个进程监听同一个端口8080

 

转载请注明:轻风博客 » Go程序的优雅重启机制

喜欢 (0)or分享 (0)