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

ReactPHP Keep-Alive连接引发内存占用过高问题及禁用咨询

ReactPHP + FastRoute API 长连接内存泄漏问题

我用ReactPHP和FastRoute开发了一个REST API,发现当Web界面请求带Connection: keep-alive头时,内存会持续增长直到崩溃;换成Connection: close就没有内存泄漏。想问两个问题:

  1. 这个问题的成因是什么?
  2. 能不能在ReactPHP服务器里禁用Keep-Alive?

我的服务器代码如下:

$server = new Server($loop, new ErrorHandler(), new JsonRequestDecoder(), new CorsMiddleware([
    'allow_origin' => [
        '*',
        'http://localhost:3000'
    ],
    'allow_methods'     => ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'],
    'allow_headers'     => ['DNT','X-Custom-Header','Keep-Alive','User-Agent','X-Requested-With','If-Modified-Since','Cache-Control','Content-Type','Content-Range','Range'],
    'expose_headers'    => ['DNT','X-Custom-Header','Keep-Alive','User-Agent','X-Requested-With','If-Modified-Since','Cache-Control','Content-Type','Content-Range','Range']
 
]), new Router($routes));

问题成因

  • 长连接资源未释放:Keep-Alive会维持TCP连接供后续请求复用,如果你的代码在处理请求后没有正确释放对应资源(比如数据库连接、文件句柄、临时变量、事件监听器等),这些资源会随着长连接的持续存在不断累积,导致内存占用攀升。
  • 请求上下文残留引用:ReactPHP的异步模型中,长连接会关联请求上下文。如果业务逻辑里的闭包、回调持有上下文对象的引用,或者没有清理请求级别的缓存/数据,这些引用会阻止PHP垃圾回收机制回收内存,最终造成泄漏。
  • 中间件/路由逻辑内存泄漏:检查使用的中间件(如JsonRequestDecoder、CorsMiddleware)或自定义路由处理函数,是否在每次请求后留下未清理的资源。比如某些中间件可能会在请求对象上附加数据,但长连接复用请求对象时未重置这些数据,导致内存堆积。

如何禁用Keep-Alive

ReactPHP的Server没有直接的配置开关,但可以通过两种方式强制关闭长连接:

方法1:在所有响应中添加Connection: close头

在路由处理函数或全局逻辑中,给每个响应主动设置该头,告知客户端不要复用连接:

// 示例路由处理逻辑
$routes->addRoute('GET', '/api/data', function ($request) {
    $data = ['status' => 'ok', 'data' => []];
    return new Response(200, [
        'Connection' => 'close',
        'Content-Type' => 'application/json'
    ], json_encode($data));
});

方法2:自定义中间件强制关闭长连接

编写全局中间件,统一处理请求和响应,确保强制关闭连接:

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ResponseInterface;

class DisableKeepAliveMiddleware implements MiddlewareInterface
{
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // 移除请求中的Keep-Alive相关头
        $request = $request->withoutHeader('Connection');
        // 处理请求
        $response = $handler->handle($request);
        // 添加响应头强制关闭连接
        return $response->withHeader('Connection', 'close');
    }
}

// 将该中间件加入Server的中间件链(建议放在最前面)
$server = new Server($loop, new ErrorHandler(), new DisableKeepAliveMiddleware(), new JsonRequestDecoder(), new CorsMiddleware([
    // 你的Cors配置
]), new Router($routes));

注意:如果使用CorsMiddleware,需确保expose_headers包含Connection,避免跨域读取头的限制问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:46:11