Swoole常见Worker崩溃原因_Swoole进程崩溃故障方法【方法】

1次阅读

worker崩溃典型现象是日志中反复出现workererror回调或“worker_id=2 exited, code=255, signal=0”;第一判断线索为该输出或请求超时、连接积、内存持续上涨。

Swoole常见Worker崩溃原因_Swoole进程崩溃故障方法【方法】

Worker崩溃的典型现象和第一判断线索

看到日志里反复出现 WorkerError 回调被触发,或者 worker_id=2 exited, code=255, signal=0 这类输出,基本能确认是 Worker 进程非正常退出。更隐蔽的是进程没报错但请求开始超时、连接堆积、内存持续上涨——这往往是未捕获异常或内存泄漏导致的“慢性崩溃”,比直接段错误更难定位。

致命错误(E_ERROR/E_PARSE)怎么捕获不到?

PHP 的致命错误不会抛出 Exceptiontry-catch 完全无效,必须靠 register_shutdown_function + error_get_last() 组合兜底。但要注意:这个函数只在当前 Worker 进程内生效,必须在 WorkerStart 里注册,而不是全局写一次。

  • 漏掉 workerstart 回调里的注册,整个 Worker 就失去兜底能力
  • error_get_last() 返回 NULL 时别硬解析,要先判空
  • 记录日志时务必带上 $workerId 和时间戳,否则多进程日志混在一起根本分不清谁挂了

为什么 max_request 设成 0 反而更容易崩?

设为 0 表示永不重启 Worker,等于把内存泄漏、资源句柄累积、静态变量污染等所有问题都堆在一个进程里。实际生产中,max_request 是最廉价的“防崩保险丝”。它不解决根本问题,但能阻止单个 Worker 恶化到 segfault 或 OOM。

  • 常规值建议 1000–5000,高内存消耗服务(如图片处理)可压到 500 以下
  • 搭配 max_request_grace 使用,避免请求中途被砍断
  • 如果发现 Worker 总是在接近 max_request 时退出,说明不是配置问题,而是真有泄漏——该查代码了

段错误(SIGSEGV)和信号退出怎么快速区分?

WorkerError 回调里的 $signal 值是关键:11 是 SIGSEGV(段错误),9 是 SIGKILL(大概率被 OOM Killer 干掉),15 是 SIGTERM(人为 kill 或 systemd 停止)。别光看 exit_code,信号值才是真相。

  • dmesg -T | grep -i "killed process" 确认是否 OOM
  • 段错误必须开 core dump:ulimit -c unlimited + echo "/tmp/core.%e.%p" > /proc/sys/kernel/core_pattern
  • gdb php core.xxx帧,重点看 extension 调用或 C 扩展传参是否越界

swoole 的崩溃恢复机制本身很稳,但真正麻烦的从来不是“重启”,而是重启后同一行代码继续崩——那说明你还没找到那个藏在协程里、静态变量中、或扩展底层的幽灵问题。

text=ZqhQzanResources