最近优化了一版程序:用到了golang的优雅退出机制。
程序使用leader/follower分布式高可用模型,所有的请求都会命中leader;
使用etcd的election sdk
做选主,需要在节点意外下线的时候,主动去etcd卸任(删除10s租约), 否则已经下线的节点还会被etcd认为是leader。
所以在这里,优雅退出是技术刚需。
另外根据[云原生十二要素方法论] 第9条: 快速启动和优雅终止可最大化健壮性 , 也推荐各位遵守实践。 Fast startup and shutdown are advocated for a more robust and resilient system.
粗浅的认知方案:捕获程序的终止信号, 主动去卸任。
进程间通信信号是操作系统提供的信号机制的内容, 它不是我们开发者长陷入其中的网络或者Socket通信。
kill -l 命令可以列出系统支持的所有进程间通信信号, 下面粗体是常见的、可能用到的通信信号
abort()
函数产生,用于异常终止一个进程。alarm()
函数产生,用于定时通知进程。有进程终止效果的常用信号有三个:SIGINT、 SIGKILL、SIGTERM, 其中SIGKILL(kill -9)
无法被应用捕获或忽略。
一般应用捕获SIGINT(interrupt中断)、SIGTERM(terminate终止)信号就可在终止之前注入行为。
golang提供signal
包来监听收到的进程间通信信号。
针对长时间运行的程序,新开协程,持续监听信号,并插入优雅关闭的代码。
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGTERM, syscall.SIGINT)
go func() {
select {
case sig:= <-c: {
log.Infof("Got %s signal. Aborting...\n", sig)
eCli.Close() // 利用 etcd election sdk主动卸任
os.Exit(1)
}
}
}()
SIGSTOP:暂停进程, 这意味着进程挂起,直到收到SIGCONT信号(continue)才能继续运行。
Q: 进程暂停是什么状态?
1> .收到SIGSTOP信号, 进程会停止运行, 不会执行任何代码,直到被显式恢复; 2>. 不可忽略,这意味着进程收到信号,无法自行决定如何响应,操作系统会直接暂停它; 3>. 资源保持, 虽然被暂停,但依然保留所有系统资源(内存、文件描述符), 这不像进程终止,会释放所有资源。
client===> A===>B, 模拟进程B阻塞:
1>. 对进程B执行kill -STOP {pid} 暂停进程
2>. time curl 192.168.8.88/test/timeoutAPI 输出:
0.01s user 0.01s system 0% cpu 10.168 total
// 这意味着进程A请求B的超时时间是10s
上面的STOP信号是纯正的暂停信号,进程无法拒绝;
HangUp信号最初用于终端断开时通知应用进程, 默认行为是终止进程;
由于HUP信号可被应用捕获,在现代应用中,HUP信号常用于通知守护进程重新加载其配置文件。
Nginx master进程重写了HUP信号默认终止进程的逻辑,自定义了处理逻辑,实现了配置的热更新。
btw, 在机器与内master进程直接交互, 不是特别便利;
nginx 0.8版本之后,给出了一系列命令行参数, nginx -s reload这个命令会启动一个nginx前台进程,自动定位master进程,向master进程发送HUP信号。
相关资料:https://tengine.taobao.org/book/chapter_02.html#id1
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有