全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-21 6 分钟 ✍️ juanwangdev

优雅启动与关闭

容器优雅停机确保数据一致性,下面介绍信号处理与配置方法。

信号处理

停机流程

dockerfile
docker stop my-app
    ↓
发送 SIGTERM (默认等待 10s)
    ↓
容器处理中请求
    ↓
清理资源(关闭连接、刷盘)
    ↓
进程退出
    ↓
(超时 10s 后)
    ↓
发送 SIGKILL (强制终止)

信号处理示例

JavaScript
# Node.js 应用
FROM node:18

COPY server.js .

# PID 1 问题:shell 不转发信号
# CMD ["node", "server.js"]  # 错误:shell 格式

# 正确:exec 格式
CMD ["node", "server.js"]
Bash
// server.js
process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down gracefully');
  server.close(() => {
    console.log('Closed all connections');
    process.exit(0);
  });
});

process.on('SIGKILL', () => {
  console.log('SIGKILL received, forcing exit');
  process.exit(1);
});

stop_grace_period

dockerfile
# 配置超时时间(默认 10s)
docker run -d --name my-app --stop-timeout 30 my-app

# Compose 配置
services:
  app:
    image: my-app
    stop_grace_period: 30s

超时后发送 SIGKILL 强制终止,可能丢失数据。

PID 1 问题

Shell 格式 vs Exec 格式

dockerfile
# Shell 格式(不推荐)
CMD node server.js
# 启动 /bin/sh -c "node server.js"
# SIGTERM 发给 shell,不转发给 node

# Exec 格式(推荐)
CMD ["node", "server.js"]
# 直接启动 node server.js
# SIGTERM 直接发给 node

tini 解决方案

Bash
# 安装 tini
RUN apt-get install -y tini

# 使用 tini 作为 init 系统
ENTRYPOINT ["tini", "--"]
CMD ["node", "server.js"]

tini 是轻量级 init 系统,正确转发信号并回收僵尸进程。

优雅启动

预热检查

Java
#!/bin/bash
# entrypoint.sh

# 预热缓存
echo "Warming up cache..."
curl -s http://localhost:3000/warmup

# 检查依赖
until nc -z db 5432; do
  echo "Waiting for DB..."
  sleep 1
done

echo "Starting application..."
exec "$@"

优雅关闭示例

Java

Python
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
  System.out.println("Shutting down gracefully");
  dataSource.close();
  server.stop();
}));

Python

text
import signal
import sys

def graceful_shutdown(signum, frame):
    print("Shutting down gracefully")
    server.close()
    sys.exit(0)

signal.signal(signal.SIGTERM, graceful_shutdown)

要点总结

  • docker stop 先发送 SIGTERM,等待 10s 后发送 SIGKILL
  • Exec 格式 CMD 确保信号直接传给进程,Shell 格式会被 shell 拦截
  • stop_grace_period 配置超时,避免过早强制终止
  • tini 作为 init 系统正确转发信号并回收僵尸进程
  • 应用需处理 SIGTERM 信号,完成请求处理和资源清理

📝 发现内容有误?点击此处直接编辑

← 上一篇 镜像供应链安全
下一篇 → 健康检查与自愈
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库