swoole优雅停机需在server创建前用swoole\process::signal注册sigterm/sigint,仅主进程注册一次,回调中调用$server->shutdown()且禁用exit/die;worker内用swoole\exitexception替代die;shutdown后需广播通知、清定时器、取消异步任务,并设5秒超时强制close fd;systemd中须配置killmode=mixed和oomscoreadjust=-500。

在Swoole服务运行中,收到SIGTERM却立即断连、kill后Worker进程消失但日志无迹可寻、用exit终止Task进程导致整个服务挂掉——这些都不是代码逻辑问题,而是信号注册位置错误或退出方式违反Swoole进程模型所致。
主进程信号注册必须在Server启动前完成
第一步:在new Swoole\Http\Server()之前,调用Swoole\Process::signal()注册信号处理器。
第二步:只在master进程注册一次,不要在onWorkerStart或onTaskStart里重复注册——子进程会自动继承信号上下文,重复注册会导致信号被覆盖或丢失。
第三步:注册SIGTERM和SIGINT,回调函数内直接调用$server->shutdown(),【禁止在此处执行exit、die或throw新异常】。
这一步操作起来很简单,直接把signal注册写在new Server前面就行;但若放在onStart之后,master进程已进入事件循环,信号钩子将无法生效。
Worker进程不能主动调用exit/die
方法一:业务代码中所有可能中断流程的地方,用throw new Swoole\ExitException替代exit()或die()。
方法二:全局包裹try/catch,在onRequest/onReceive等回调最外层捕获Swoole\ExitException并return,让Worker自然结束当前协程后退出。
注意:PHP原生的set_exception_handler在Swoole中完全失效,【必须每个回调手动加try/catch】,否则未捕获异常会直接触发Worker进程退出并返回status=255。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
优雅关闭需分阶段释放资源
收到SIGTERM后,仅调用$server->shutdown()只是第一步。它停止accept新连接,但不会主动关闭已有TCP连接或HTTP长连接。
必须紧接着做三件事:广播关闭通知给所有活跃连接、清理定时器(Timer::clearAll())、取消未完成的异步任务(Async::wait()或Channel::pop超时处理)。
最后设置一个5秒超时计时器,超时后强制close所有fd,避免因客户端不响应而永久阻塞进程退出。
systemd托管时必须对齐KillMode与OOMScoreAdjust
在/etc/systemd/system/swoole.service中,添加两行关键配置:
KillMode=mixed —— 确保SIGTERM只发给master进程,不误杀worker。
OOMScoreAdjust=-500 —— 降低Worker被Linux OOM Killer选中的概率,防止内存稍高就被强制SIGKILL终结。
缺省KillMode=control-group会导致systemd向整个cgroup发SIGKILL,这是Worker莫名消失的最常见系统层原因。










