workerman无内置进程内存上限配置,需组合防控:设php memory_limit、用max_requests轮换进程、定时器监控memory_get_usage(true)并exit、规避大文件加载和text协议未防护等风险点。

Workerman 本身不提供“进程级内存上限”配置项,也不能像 Nginx 或 Node.js 那样通过参数直接限制单个 Worker 进程的内存使用量。在 Workerman 5.2.3 中,没有内置的 memory_limit 或类似机制来硬性阻止进程超过某内存阈值后自动重启或拒绝服务。 所谓“设置内存上限防止溢出”,本质是组合策略防控,而非一键开关。
下面这些做法才是实际有效、已在生产环境验证的方式:
明确 PHP 自身的内存限制
这是最基础的一层防线:
- 在 Worker 启动脚本(如
start.php)顶部或 CLI 环境中,用ini_set('memory_limit', '256M');设置(注意:必须早于任何大对象初始化) - 或在系统层面通过
php -d memory_limit=256M start.php启动,避免被 php.ini 全局值干扰 - ⚠️ 该限制仅在 PHP 内存分配超限时抛出
Fatal error: Allowed memory size exhausted,不会优雅降级,且对已泄漏但未突破阈值的场景无效
利用 max_requests 主动轮换进程
这是 Workerman 最可靠、最常用的防内存累积手段:
- 在启动前设置:
Worker::$max_requests = 1000; - 表示每个 Worker 子进程最多处理 1000 次请求(对 WebSocket/长连接,指接收并完成处理的消息次数,非 TCP 连接数)
- 达到后进程自动退出,主进程拉起新实例,内存彻底清零
- 建议值:普通聊天服务设 500–2000;高数据处理类(如消息广播、文件解析)建议 200–500,并配合监控调优
实时监控 + 主动干预
靠被动等崩溃不行,得主动盯住内存水位:
- 在定时器中定期检查:
Timer::add(10, function () { $mem = memory_get_usage(true); if ($mem > 1024 * 1024 * 200) { // 超过 200MB echo "High memory usage: {$mem} bytes\n"; // 可选:记录日志、触发告警、或主动 exit 让 max_requests 机制接管 } }); - 结合
memory_get_peak_usage()观察趋势,比瞬时值更有参考价值
关键规避动作(比“设上限”更重要)
很多 OOM 根本不是慢泄漏,而是单次操作踩雷:
- 发大文件不用
file_get_contents() + send(),改用$connection->sendfile($path)—— 零拷贝,不进 PHP 内存 - Text 协议必须显式启用防护:
$worker->protocol = \Workerman\Protocols\TextProtocol::class; $worker->transport = 'tcp'; $worker->onMessage = function ($connection, $data) { /* ... */ }; // 必须传配置,否则无保护 $worker->protocol = new \Workerman\Protocols\TextProtocol([ 'max_package_size' => 1024 * 1024, // 1MB 封顶 'strict_mode' => true, ]); - 避免在连接对象或全局静态变量中缓存大量数据(如
$connection->cache = [...];),尤其不要存整个数据库结果集或文件内容
不复杂但容易忽略。











