一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

借助 docker restart 做到容器平滑重启与连接回收

时间:2026-07-10 09:58:47 编辑:袖梨 来源:一聚教程网

docker restart 不是平滑重启,因它强制终止容器再启动新实例,导致连接中断;需应用支持优雅关闭、负载均衡器 draining 及外部状态分离才能实现真正平滑重启。

docker restart 本身不提供“平滑重启”能力——它会强制终止容器进程再启动新实例,连接会中断。真正的平滑重启(如零停机、连接优雅关闭)需配合应用层支持与额外配置,而非单纯依赖 docker restart 命令。

为什么 docker restart 不是平滑的

执行 docker restart 时,Docker 实际执行的是:

  • 向容器主进程(PID 1)发送 SIGTERM 信号,等待默认 10 秒(可通过 --stop-timeout 调整)
  • 超时后若进程未退出,则发送 SIGKILL 强制终止
  • 立即基于原镜像和配置拉起一个全新容器实例

整个过程无状态保留、无连接迁移,客户端 TCP 连接会被重置(RST),长连接(如 WebSocket、数据库连接池)直接断开,无法满足“平滑”要求。

实现真正平滑重启的关键条件

要让服务在容器重启期间保持可用,必须满足以下至少两项:

  • 应用自身支持优雅关闭:监听 SIGTERM,停止接收新请求,完成正在处理的请求,释放资源后再退出
  • 前置负载均衡器(如 Nginx、Traefik、HAProxy)启用健康检查与连接 draining:在重启前将该实例从上游摘除,待活跃连接自然结束
  • 外部状态分离:会话、缓存、数据库连接等不依赖容器本地内存,避免重启导致状态丢失

推荐的平滑重启操作流程

以 Web 服务为例,不依赖 docker restart,而是采用滚动更新或就地优雅切换:

  • 使用 docker-compose up --force-recreate --no-deps -d service_name 启动新实例,并配合 healthcheckdeploy.restart_policy
  • 在 docker-compose.yml 中配置健康检查与部署参数:
    services:  web:    image: myapp:latest    healthcheck:      test: ["CMD", "curl", "-f", "http://localhost/health"]      interval: 10s      timeout: 5s      retries: 3      start_period: 40s    deploy:      update_config:        parallelism: 1        delay: 10s        failure_action: rollback        order: stop-first  # 先停旧容器,等新容器健康后再删旧实例
  • 若必须单容器操作,可手动触发优雅流程:
    • 先调用应用提供的 shutdown 接口(如 curl -X POST http://localhost/shutdown
    • 确认连接数归零(如 ss -tn sport = :80 | wc -l
    • 再执行 docker stop container_name(依赖应用响应 SIGTERM)
    • 最后 docker start container_namedocker run 新实例

连接回收的配套实践

容器重启后,旧连接残留可能引发 TIME_WAIT 占用或客户端重试风暴。需协同处理:

  • 客户端侧:启用连接复用(Keep-Alive)、设置合理超时(read/write timeout ≥ 30s)、实现幂等重试逻辑
  • 服务端侧:在应用中关闭 keep-alive 连接前发送 Connection: close 响应头;对数据库连接池配置最大空闲时间与验证查询
  • 内核层面(可选):调整宿主机 net.ipv4.tcp_fin_timeout 等参数,加快 TIME_WAIT 回收,但不建议替代应用层设计

热门栏目