直接调用exit或die会杀死整个Worker进程而非仅退出当前协程;因其是PHP进程级终止指令,不感知协程上下文,Swoole 4.1.0+仅拦截exit并抛出Swoole\ExitException,die则完全绕过拦截直杀进程。

在Swoole常驻进程中,直接调用exit或die会导致整个Worker进程立即终止,而非仅退出当前协程——所有并发HTTP请求、定时器、异步任务全部中断,连接未释放,资源泄漏,Manager进程被迫重启该Worker,引发雪崩式故障。
为什么exit/die会杀死整个进程
PHP原生的exit和die是进程级终止指令,底层调用exit(3)系统调用,不感知协程上下文。Swoole Worker是常驻进程,一旦触发,内核直接回收该进程空间,所有协程强制销毁,无任何清理机会。
【die完全绕过Swoole拦截机制】 Swoole 4.1.0+仅对exit()做了底层拦截并抛出Swoole\ExitException,但die作为PHP语言别名,未被统一处理,仍直通系统exit,风险更高。
这一步操作起来很简单,直接把die('err')写进onRequest回调里,就能复现502错误——但后果严重,不可逆。
正确退出当前协程的方法
方法一:用return提前结束回调函数
在onRequest、onReceive等回调中,直接return即可退出当前协程逻辑,不影响其他协程运行。这是最轻量、最安全的方式。
方法二:抛出自定义异常并捕获
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
在协程内throw new RuntimeException('abort'),外层用try/catch包裹业务逻辑。注意:【Swoole不支持set_exception_handler】,必须在每个回调内部显式捕获,否则仍会退出Worker。
方法三:使用Swoole\ExitException(仅限exit)
① 确保你在协程上下文中调用exit(0)(如go(function(){ exit(0); }));
② 外层必须try/catch Swoole\ExitException $e;
③ 调用$e->getStatus()获取退出码,再执行清理逻辑;
④ 切记不能用die,也不能在非协程环境(如onStart)中调用exit,否则照样杀进程。
如何检测代码中是否误用了exit/die
grep -r 'exit\|die' --include="*.php" ./src/ | grep -v 'exit\|die.*//' | grep -v '\/\*.*exit.*\*\/'
这条命令能扫出所有未注释掉的exit和die调用点。重点检查onRequest、onReceive、onConnect等事件回调文件,以及封装的公共工具类。
发现后立刻替换为return或异常抛出——不要心存侥幸,线上一次die就可能引发整机请求丢弃。
















