Rust 优雅关闭
处理信号、停止接新请求、排空进行中任务与超时强杀的服务关闭协议。
#type / concept
#status / growing
#tech / dev
#resource / rust
[!info] 关联笔记
Rust 优雅关闭
这个概念为什么出现
kill -9 式退出会打断请求、丢消息。
优雅关闭:收信号 → 停止准入 → 等待飞行中工作 → 释放资源 → 退出。
[!abstract] 一句话理解 监听 SIGTERM/SIGINT,取消服务 future,给飞行中请求一个宽限期,超时再强制结束。
最小可运行示例
场景:关闭协议状态机(逻辑示意)
// 业务意图:用枚举表达关闭阶段。
// 教学点:阶段清晰;真实实现接 signal hook。
#[derive(Debug)]
enum Phase {
Running,
Draining,
Stopped,
}
fn main() {
let mut phase = Phase::Running;
println!("got SIGTERM");
phase = Phase::Draining;
println!("wait in-flight <= 30s: {phase:?}");
phase = Phase::Stopped;
println!("exit 0: {phase:?}");
}
Tokio 中常见:signal::ctrl_c() 与 axum::serve(...).with_graceful_shutdown(...)。
结合场景再看三个关注点
- K8s 先 SIGTERM
- ** readiness 先失败再排空**
- 超时防挂死
工程实践
- 统一 CancellationToken
- 工作者监听取消
- 关闭指标
- 本地用 ctrl-c 测
本节总结
- 关闭是协议
- 信号 + 排空 + 超时
- 与编排系统协作
自测题
- 为何 readiness 要在 drain 前变失败?
- 只有 Drop 够不够?
参考答案
- 停止新流量进入。
- 不够,需要协作式停止异步任务与监听端口。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Tokio signal | 生态 | 信号 |
| axum graceful shutdown examples | 生态 | 框架集成 |