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

PHP 8.1环境下Laravel结合Swoole运行出现HTTP 408及Worker进程被Manager进程异常终止问题排查求助

Laravel + Swoole (PHP 8.1): Worker进程被Master进程SIGKILL导致HTTP 408错误

从你提供的日志和环境信息来看,核心问题是Swoole的Master进程主动发送SIGKILL信号杀死了Worker进程,进而导致部分请求返回408超时。下面我们一步步分析原因并给出解决方案:

问题复现与日志分析

首先,你遇到的现象是部分请求偶尔返回HTTP 408,查看Swoole日志发现Worker异常退出:

[2022-07-29 08:59:52 $28.0] WARNING Server::check_worker_exit_status(): worker(pid=49, id=4) abnormal exit, status=0, signal=9

通过strace监控确认是Master进程(pid=54)发起的杀死操作:

54 13:27:40.909415 kill(1608, 0) = 0
54 13:27:40.909598 kill(1608, SIGKILL) = 0
1608 13:27:40.943992 +++ killed by SIGKILL +++

环境信息确认

你的环境配置如下:

PHP版本

PHP 8.1.8 (cli) (built: Jul 11 2022 08:30:39) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.8, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.8, Copyright (c), by Zend Technologies

Swoole扩展

swoole
Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 4.8.10
Built => Jul 6 2022 13:14:29
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
sockets => enabled
openssl => OpenSSL 3.0.2 15 Mar 2022
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
pcre => enabled
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
mysqlnd => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608

Laravel版本

Laravel Framework 9.21.3

系统与编译器

Linux 9968d896fe6c 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.2.0-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-gBFGDP/gcc-11-11.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-gBFGDP/gcc-11-11.2.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.2.0 (Ubuntu 11.2.0-19ubuntu1)

问题根源分析

Master进程发送SIGKILL通常是因为Worker进程触发了Swoole的健康检查机制,常见原因包括:

  1. Worker进程长时间无响应:比如请求处理陷入死循环、阻塞IO操作超时,导致Master的心跳检测判定Worker异常。
  2. 内存泄漏超限:Laravel在常驻内存环境下的资源泄漏(如未释放的数据库连接、静态变量累积)导致Worker内存占用超过阈值,被Master强制终止。
  3. 协程调度失衡:当前swoole.enable_preemptive_scheduler为Off,单个协程可能长时间占用CPU,导致Worker无法响应Master的心跳检测。

解决方案

1. 优化Swoole服务器配置

调整以下关键参数,增强Worker进程的稳定性:

$server = new Swoole\Http\Server('0.0.0.0', 9501);
$server->set([
    // 限制Worker处理请求数,达到后自动重启,避免内存泄漏
    'worker_max_request' => 1000,
    // 心跳检测:每30秒检查一次,60秒无响应则杀死Worker
    'heartbeat_check_interval' => 30,
    'heartbeat_idle_time' => 60,
    // 设置Worker内存上限(单位:字节,这里是128M)
    'worker_memory_limit' => 134217728,
    // 开启协程抢占调度,避免单个协程独占CPU
    'enable_preemptive_scheduler' => true,
]);

2. 修复Laravel的资源泄漏问题

Laravel的设计默认是短生命周期的,在Swoole常驻环境下需要手动清理资源:

  • 添加请求终止中间件,释放数据库、Redis等连接:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class CleanupResources
{
    public function handle(Request $request, Closure $next)
    {
        return $next($request);
    }

    public function terminate(Request $request, $response)
    {
        // 断开数据库连接
        DB::disconnect();
        // 断开Redis连接(如果使用)
        if (class_exists(Redis::class)) {
            Redis::disconnect();
        }
        // 重置应用实例(可选,根据Laravel版本调整)
        app()->flush();
    }
}

将这个中间件注册到app/Http/Kernel.php的web或api中间件组中。

  • 禁用不必要的服务:如果是API服务,可在config/app.php中禁用Session、Cookie等非必需服务,减少资源占用。

3. 升级Swoole版本

你当前使用的Swoole 4.8.10存在一些与PHP 8.1兼容性相关的已知问题,建议升级到4.8.x系列的最新稳定版或5.x版本,新版本修复了不少协程和进程管理的Bug。

4. 监控Worker进程状态

添加自定义日志,记录Worker的内存、CPU和请求处理时间,定位异常请求:

$server->on('Request', function ($request, $response) {
    $startMem = memory_get_usage(true);
    $startTime = microtime(true);

    // 处理Laravel请求
    $app = require __DIR__.'/bootstrap/app.php';
    $kernel = $app->make(\Illuminate\Contracts\Http\Kernel::class);
    $laravelResp = $kernel->handle($laravelReq = \Illuminate\Http\Request::capture());

    // 记录监控数据
    $endMem = memory_get_usage(true);
    $costTime = round((microtime(true) - $startTime) * 1000, 2);
    error_log(sprintf(
        "[Worker %d] Request: %s | Time: %sms | Mem: %sKB",
        swoole_get_current_worker_id(),
        $laravelReq->getPathInfo(),
        $costTime,
        round(($endMem - $startMem)/1024, 2)
    ));

    // 发送响应并清理
    $response->header('Content-Type', 'text/html; charset=utf-8');
    $response->end($laravelResp->getContent());
    $kernel->terminate($laravelReq, $laravelResp);
});

5. 调整系统资源限制

确保系统的文件句柄和进程数限制足够:

# 临时设置打开文件数上限
ulimit -n 65535
# 永久设置(编辑/etc/security/limits.conf)
echo "www soft nofile 65535" >> /etc/security/limits.conf
echo "www hard nofile 65535" >> /etc/security/limits.conf

总结

先从调整Swoole的worker_max_request和心跳参数入手,同时修复Laravel的资源泄漏问题,这两个步骤解决大部分此类问题。如果问题仍存在,再升级Swoole版本并添加监控日志定位具体异常请求。

内容的提问来源于stack exchange,提问作者Omer SAVAS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:27:37