You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Swarm环境下如何软重启PHP worker容器 避免中断运行中任务

Docker Swarm下PHP Worker无中断软重启实现方案

以下是完全符合你需求的软重启实现方案,全程不会中断正在运行的任务:

1. 改造PHP Worker脚本,支持信号捕获

首先需要开启PHP的pcntl扩展(处理进程信号),在脚本中捕获Docker停止时默认发送的SIGTERM信号,设置终止标记,等待当前任务处理完成后再退出脚本:

<?php
// 开启信号回调检测
declare(ticks = 1);
$stopFlag = false;

// 捕获SIGTERM信号,设置终止标记
pcntl_signal(SIGTERM, function () use (&$stopFlag) {
    $stopFlag = true;
});

// Gearman Worker初始化逻辑
$worker = new GearmanWorker();
$worker->addServer('你的Gearman服务地址', 4730);
$worker->addFunction('你的任务处理方法名', '实际处理任务的函数名');

// 循环逻辑增加终止标记判断
while (!$stopFlag && $worker->work()) {
    // 处理完当前任务后检查是否需要退出
    if ($stopFlag) {
        // 可在此处增加退出日志、资源释放逻辑
        exit(0);
    }
    // 无任务时可加短休眠降低CPU占用
    usleep(100000);
}

Debian10环境下可直接通过apt install php7.4-pcntl安装扩展。

2. 配置Docker优雅停止参数

Docker默认停止容器时只会等待10秒,之后就会发送SIGKILL强制终止进程,需要调整宽限期匹配你的任务最长执行时长:

  • 在Dockerfile中增加配置:STOPSIGNAL SIGTERM,明确容器停止时发送的信号为SIGTERM
  • 启动/更新Service时增加--stop-grace-period 300s参数,将宽限期设为5分钟(可根据你的任务最大执行时长调整)

3. 执行软重启操作

因为你仅需要更新PHP脚本、不需要更换镜像,建议将PHP脚本目录通过bind mount挂载到宿主机,先更新宿主机上的脚本文件,再执行以下两种操作任选其一即可:

方案A:批量滚动软重启(适合多副本场景)

docker service update \
  --update-parallelism 2 \ # 每次同时重启2个容器,可根据总副本数调整
  --update-delay 10s \ # 每批重启的间隔时间,保证前一批容器正常退出重启完成
  --stop-grace-period 300s \
  PHP-worker

方案B:逐个手动软重启(适合小流量场景,避免批量重启导致消费堆积)

先通过docker ps找到运行PHP-worker的容器ID,逐个发送SIGTERM信号即可:

docker kill --signal=SIGTERM <容器ID>

容器收到信号完成当前任务后会自动退出,Docker Swarm会自动拉起新的容器加载更新后的脚本。

注意事项

  • 滚动更新的并行数不要设置过大,保证重启过程中有足够的worker在运行,避免Gearman任务堆积
  • 停止宽限期必须大于你单个任务的最长执行时间,避免未处理完的任务被强制终止
  • 若你的脚本没有挂载到宿主机,需要先构建新的镜像(包含更新后的PHP脚本),再执行docker service update --image 新镜像名 PHP-worker,同样可以实现软重启效果

内容的提问来源于stack exchange,提问作者Guido Leibbrand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 02:45:08