max_request

设置worker进程的最大任务数,默认为0,一个worker进程在处理完超过此数值的任务后将自动退出,进程退出后会释放所有内存和资源。

这个参数的主要作用是解决由于程序编码不规范导致的PHP进程内存泄露问题。PHP应用程序有缓慢的内存泄漏,但无法定位到具体原因、无法解决,可以通过设置max_request临时解决。

  • max_request只能用于同步阻塞、无状态的请求响应式服务器程序, 强烈不推荐在异步/协程服务器中使用
  • 在swoole中真正维持客户端TCP连接的是master进程,worker进程仅处理客户端发送来的请求,因为客户端是不需要感知Worker进程重启的
  • 纯异步的Server不应当设置max_request
  • 使用Base模式时max_request是无效的

当worker进程内发生致命错误或者人工执行exit时,进程会自动退出。master进程会重新启动一个新的worker进程来继续处理请求

实例代码

创建一个swoole tcp server,我们开启两个worker进程,dispatch mode设置为3(抢占模式),文件名保存为server.php,代码如下:

<?php
$serv = new swoole_server("127.0.0.1", 9501);
$serv->set(array(
    'worker_num' => 2,    //开启两个worker进程
    'max_request' => 3,   //每个worker进程max request设置为3次
    'dispatch_mode'=>3,
));
//监听数据接收事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
    $serv->send($fd, "Server: ".$data);
});
//启动服务器
$serv->start();

使用php server.php开启服务后,首先使用 ps aux | grep server.php 看下一下进程PID,一共有四个进程,如图所示:

其中8430和8431分别是master进程和manager进程,剩下两个8434和8435则是两个worker进程。 按照预想,如果我们执行5次请求,那么必然会有一个worker进程会退出并被重新拉起一个新的,结果如下图所示:

注意pid为8434的worker进程已经没有了,新出现的则是pid为8457的worker进程



  • 飞鸿影

    max_request,是处理这么多请求之后,重启worker进程. 如果代码没有内存泄露的问题,没有每访问一次,内存就增加一点,那不设置也不会有内存泄露. 反之,max_request,就可以限制内存无限制增长,从而防止内存泄露.

  • Xcode_swift

    worker_num设置的n实际开启总是n+1

  • rocwu

    请问,max_request在纯异步模式下的支持,有什么计划吗?

  • 有明

    纯异步模式下 Swoole 是无法探知业务逻辑何时处理结束(同步模式下,Swoole 认为回调函数结束就是业务处理的结束),这就需要业务的编写者自己来控制进程的重启,这样才能避免任有业务时被强行终止。

  • lyy

    我的worker里会有一段基于协程的轮循,当这个worker达到设置的max_request后重启,里面的协程是不是也就没法恢复了?

  • wjmrli

    可以通过设置 'reload_async' => true 让 worker 在 协程结束后再退出

  • finding

    只适用于同步阻塞,指的是客户端的同步阻塞吧?上面的示例代码明显是异步的