task_max_request 是 task 进程处理异步任务的上限,max_request 是 worker 进程处理客户端请求的上限;二者作用对象、生命周期、计数时机均不同,不可混用。

task_max_request 是什么,和 max_request 有什么区别
task_max_request 控制的是 task 进程 处理任务的上限,不是 worker 进程;max_request 控制的是 worker 进程 处理请求的上限。两者作用对象不同,生命周期不同,不能混用或互相替代。
worker 进程负责接收和响应客户端请求(如 HTTP、TCP),而 task 进程只处理 $server->task() 投递的异步任务,不直接接触网络连接。所以它们的内存泄漏路径、资源使用模式、重启时机都不同。
-
max_request在每次 request 完成后计数,适用于同步阻塞型请求处理逻辑 -
task_max_request在每次onTask回调执行完成后计数,只对 task 进程生效 - 即使没开
task_worker_num,task_max_request的设置也无效——它不会触发任何行为
task_max_request 默认值在 1.7.17+ 版本已改为 0
早期 Swoole(1.7.17 之前)默认 task_max_request 是 5000,现在默认是 0,意味着 task 进程永不自动退出。这个改动很关键:如果你从老版本升级上来,没显式设置 task_max_request,task 进程就会长期驻留,一旦有内存泄漏(比如静态变量累积、PDO 连接未释放、缓存未清理),问题会持续恶化。
要不要设?得看你的 onTask 逻辑是否「干净」:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 如果
onTask里只是简单计算、发邮件、写日志,且不持有大对象或全局状态,可以保持0 - 如果用了
static $cache = []、反复new大对象、或依赖某些未正确 cleanup 的扩展,建议设为 500–5000 之间,压测后定值 - 注意:设太小(如 100)会导致频繁 fork task 进程,带来额外调度开销和初始化成本
task_max_request 不生效的常见原因
设置了 task_max_request 却发现 task 进程一直不退出?先检查这几个硬性条件:
- 没配置
task_worker_num(哪怕设为 1),task_max_request完全不加载 - 没注册
onTask回调,Swoole 启动时会报错,根本起不来 - task 进程启动后从未执行过
onTask—— 计数器不会开始累加 - 代码里在
onTask中调用了exit或发生致命错误,进程提前退出,task_max_request就没机会触发 - 使用了 Base 模式(
reactor_num > 0 && task_worker_num > 0但未启用多进程管理),此时task_max_request无效(和max_request一样)
和 max_request 一起调优时的关键约束
两个参数不是独立的,它们共同影响进程稳定性,但存在隐含依赖:
- worker 进程退出时,正在投递中的 task 不会丢失,但若
task_max_request过小,可能在 worker 重启前,task 进程自己先退出,导致onFinish无法回调(需确保 task 进程比 worker 更“耐久”,至少不早于它退出) - 如果
task_worker_num很小(比如 1),而task_max_request又设得很低,容易出现 task 进程刚退出、新进程还没初始化完,任务队列就堆积,触发task_timeout - 别忽略
task_ipc_mode:当使用消息队列(task_ipc_mode => 2 or 3)时,task_max_request退出行为更稳定;共享内存模式下,进程退出可能引发 IPC 资源残留
真正容易被忽略的是:task 进程重启时,onWorkerStart 不会执行,但 onTask 的上下文是全新进程空间——你不能假设任何初始化逻辑(比如数据库连接、Redis 实例)在 task 进程里自动复用,必须在 onTask 内部或 onWorkerStart(仅对 worker 有效)里显式处理。










