← [ BACK_TO_NOTES ]

Rust 优雅关闭

处理信号、停止接新请求、排空进行中任务与超时强杀的服务关闭协议。

#concept #growing #dev #rust

[!info] related notes

Rust 优雅关闭

这个概念为什么出现

kill -9 式退出会打断请求、丢消息。
优雅关闭:收信号 → 停止准入 → 等待飞行中工作 → 释放资源 → 退出。

[!abstract] 一句话理解 收到停止事件后停止准入并通知工作任务,等待进行中工作与清理完成;超过宽限期后按明确策略取消或退出,不能把直接丢弃服务 future 当作排空。

最小可运行示例

场景:协作通知、等待与超时取消

先执行 cargo add tokio@1 --features macros,rt-multi-thread,time,sync。示例不监听 OS 信号或接收真实请求,专门验证关闭协调协议:

use std::time::Duration;
use tokio::{sync::oneshot, time::{sleep, timeout}};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (stop_tx, stop_rx) = oneshot::channel::<()>();
    let mut worker = tokio::spawn(async move {
        // 示例只等待停止通知;真实服务在此停止准入并排空进行中工作。
        let _ = stop_rx.await;
        sleep(Duration::from_millis(10)).await; // 模拟异步清理
        println!("drained");
    });
    println!("shutdown requested");
    let _ = stop_tx.send(()); // 确定性触发,便于无需人工信号的测试
    match timeout(Duration::from_secs(1), &mut worker).await {
        Ok(result) => result?,
        Err(_) => {
            worker.abort();
            let _ = worker.await; // 收割取消结果;不代表业务已排空
            return Err("shutdown deadline exceeded".into());
        }
    }
    println!("stopped");
    Ok(())
}

cargo run 应依次输出 shutdown requested、drained、stopped。timeout 接收 &mut JoinHandle,超时后仍持有句柄才能 abort 并 await;若把句柄按值交给 timeout,超时丢弃它会分离任务。abort 依赖任务让出执行权,不能强杀阻塞线程,最终进程截止时间仍需外部监督。

真实服务可将停止事件接到 axum 的 with_graceful_shutdown。signal::ctrl_c() 不等于 Unix SIGTERM:容器停止路径需单独监听 tokio::signal::unix::SignalKind::terminate(启用 signal feature,按目标平台条件编译),并处理监听错误。SIGKILL 无法捕获。

结合场景再看三个关注点

  1. 核实编排器的停止信号和宽限期;Kubernetes 通常先 TERM,超时再 KILL,preStop 也消耗宽限期
  2. readiness 先失败再排空;路由传播和已有连接存在延迟,服务端仍须停止准入
  3. 超时防挂死

工程实践

  1. 统一停止事件;多任务广播可使用 tokio-util 的 CancellationToken,但 cancel 只是通知,仍需追踪并等待任务
  2. 工作者监听取消
  3. 关闭指标
  4. 本地用 ctrl-c 测

本节总结

  • 关闭是协议
  • 信号 + 排空 + 超时
  • 与编排系统协作

自测题

  1. 为何 readiness 要在 drain 前变失败?
  2. 只有 Drop 够不够?
参考答案
  1. 停止新流量进入。
  2. 不够,需要协作式停止异步任务与监听端口。

延伸阅读与资料来源

资料类型支撑内容
Tokio signal生态信号
axum graceful shutdown examples生态框架集成
创建于 2026/7/15 更新于 2026/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本