优雅停机与连接 Drain 工程实践:从 Linux 信号到 Kubernetes Pod 的完整链路

生产环境中,一次失败的优雅停机可能导致客户端看到 502、数据库连接半开、消息重复消费,甚至分布式事务悬挂。本文从 Linux 信号处理出发,完整覆盖 TCP 半关闭、进程生命周期管理、连接池 Drain、Kubernetes Pod 终止链路、消息队列的 unacked 回收,到 Rust/Go/Java 的具体实现,给出可落地的生产级 Checklist。


一、问题的真正复杂度

很多工程师对\"优雅停机\"的理解就是\"捕获 SIGTERM 然后 exit(0)\",但在生产级系统中,真正的挑战分布在多个层面:

  • 网络层:正在飞行的请求怎么办?TCP 连接是 RST 还是 FIN?
  • 应用层:正在执行的 Handler 能否完成?连接池中的借出连接如何归还?
  • 中间件层:Redis/MySQL/消息队列的 client 是否注册了 close hook?编排层**:Kubernetes 的 preStop、terminationGracePeriodSeconds、Service Endpoint 摘除时序是否正确?

任何一个环节遗漏,都会导致\"看似优雅,实则翻车\"。


二、Linux 信号处理:被忽视的细节

2.1 signal() vs sigaction()

永远使用 sigaction(),不要用 signal()。原因有三:

  1. signal() 在不同 UNIX 平台行为不一致(System V 语义 vs BSD 语义),sigaction() 是 POSIX 标准
  2. sigaction() 可以指定 SA_RESTART 标志,让被信号中断的系统调用自动重启(避免 EINTR 处理遗漏)
  3. sigaction() 通过 SA_SIGINFO 获取发送者 PID、UID 等上下文信息
  4.  #include                        
                        
点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
网站二维码

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
/* 跳过导航链接 (无障碍) */ .skip-link { position: absolute; top: -100px; left: 15px; z-index: 99999; padding: 8px 16px; background: #007bff; color: #fff; font-size: 14px; border-radius: 0 0 4px 4px; text-decoration: none; transition: top 0.2s; } .skip-link:focus { top: 0; outline: 3px solid #0056b3; }