max_request不是防泄漏开关,而是进程级兜底机制;它通过定期重启worker进程重置内存状态,但无法修复泄漏根源,在Base模式、纯异步Server及Laravel-Swoole等框架硬编码场景下失效。

max_request 不是防泄漏开关,而是进程级兜底机制
它只做一件事:让 worker 进程在处理完指定数量请求后主动退出,由 manager 进程拉起新进程,从而重置内存和资源状态。这不是修复内存泄漏,而是用“重启”来掩盖泄漏——max_request=0 意味着永不重启,max_request=1000 意味着每 1000 个请求就重建一次上下文。
哪些场景下 max_request 会失效或被忽略
以下情况设了也白设:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
-
Base模式下该参数完全无效(Swoole 启动模式决定) - 纯异步 Server(如 UDP、WebSocket 长连接服务)不该设
max_request,因为连接生命周期远超单次请求 - Laravel-Swoole 和 think-swoole 默认硬编码
'max_request' => 0,改config/swoole.php里的配置不生效 - 使用
max_request_gently时若未配合onWorkerExit清理资源,重启后仍可能复现泄漏
设多少才合理:别拍脑袋,看内存增长曲线
推荐值不是固定数字,而是基于单请求平均内存增量推算:
- 先用
memory_get_peak_usage()在关键位置打点,压测 1000 次请求,观察 RSS 增长是否线性 - 若单请求涨 200KB,目标控制在 50MB 内,则
max_request ≈ 250;但此时高频重启开销太大,应优先查泄漏点 - 生产环境常见安全值是
1000~3000,前提是已确认无明显静态缓存滥用、未释放的 Redis 实例、Eloquent 全局查询缓存等 - 设成
100或500往往是掩盖问题,反而因频繁重建进程拖慢 QPS
task_max_request 和 max_request 的关键区别
两者作用对象不同,不能混用:
-
max_request控制 worker 进程(处理 HTTP/TCP 请求) -
task_max_request控制 task 进程(执行异步任务),默认从 Swoole v1.7.17 起为0(永不退出) - task 进程若长期运行且任务中用了
static $cache = [],同样会累积内存,此时需单独设task_max_request - task 进程重启不影响主服务可用性,但若任务含文件句柄或数据库连接未 close,仍会导致资源泄漏
ps aux --sort=-%mem 看 RSS + swoole_server->stats() 查连接数与请求计数,比盲目调 max_request 有用得多。

















