Swoole 4.1.0+ 中优雅退出需监听 SIGTERM/SIGINT,调用 $server->shutdown() 而非 exit(),避免协程异常中断;shutdown 后需主动关闭连接、清理定时器与异步任务,并统一协调 Worker 进程退出,确保请求完成、资源释放、状态码可信。

在 Swoole 4(特别是 4.1.0+)中,“优雅退出”不是调用 exit() 或简单杀进程就能实现的,而是一套围绕信号响应、协程生命周期、连接管理与资源释放的协同机制。关键在于:不中断正在处理的请求,不丢数据,不泄漏资源,且所有 Worker 进程行为一致。
必须监听 SIGTERM/SIGINT,禁用裸 exit()
Swoole 主进程默认不响应 Ctrl+C 或 kill $pid,必须显式注册信号处理器。但注意:
• exit(0) 在协程里会抛出 Swoole\ExitException,只终止当前协程,极易导致接口空响应或逻辑丢失;
• 真正该用的是 $server->shutdown()(对 Server)或 Swoole\Event::exit()(对协程事件循环);
• 信号回调必须轻量、非阻塞,禁止在其中调用 sleep()、数据库操作或阻塞 I/O。
- 推荐写法:主进程中用
Swoole\Process::signal(SIGTERM, fn() => $server->shutdown()) - 协程环境中优先用
Swoole\Coroutine\Signal::add(SIGTERM, ...),配合 Channel 解耦业务清理逻辑 - 绝对避免在
onRequest、onReceive回调里写exit()—— 改用return或抛出自定义异常
shutdown() 后要主动管理连接与任务
$server->shutdown() 的作用是停止监听新连接,但不会强制断开已有连接或中止运行中的协程。真正“优雅”的核心,在于给现有请求留出完成时间,并主动干预长连接:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 设置合理的
socket_close_wait_timeout(如 5–10 秒),让客户端有时间收尾 - 遍历
$server->connections,对 HTTP/WebSocket 连接广播关闭帧或发送 FIN 包 - 手动清理定时器:
Swoole\Coroutine\Timer::clearAll() - 等待异步任务结束:用
Channel或WaitGroup跟踪未完成的协程,超时后强制 cancel
Worker 进程退出需统一协调,不能各自为政
主进程触发 shutdown 后,各 Worker 进程应同步进入退出流程,否则会出现部分进程还在跑、部分已停的不一致状态:
- 主进程通过
sendMessage()向所有 Worker 发送自定义退出指令(如['cmd' => 'quit']) - 每个 Worker 在
onWorkerStart中监听消息,并在onWorkerStop前执行本地资源释放(如关闭 DB 连接池、刷缓存日志) - 不要依赖
onWorkerStop做关键清理 —— 它只在进程被信号杀死或$server->stop($worker_id)时触发,exit()不会触发它
退出状态码与监控必须可信
退出后如何判断是否真“干净”?靠状态码和信号双校验:
- 子进程用
swoole_process::exit($code)时,$code 应在 0–255 之间(负数或超限会被截断) - 父进程通过
swoole_process::wait()获取StatusInfo->exit_code和StatusInfo->signal - 优先看
signal:非零值(如 15=SIGTERM、9=SIGKILL)说明是外部干预,需告警;仅当signal === 0才信任exit_code做业务判断 - 线上务必记录
dmesg | grep -i "killed process",排查 OOM Killer 强杀

















