workerman报“too many open files”需同步调整系统、用户、进程启动环境及workerman自身四层限制:查进程真实限制用cat /proc//limits,systemd需配limitnofile,supervisord需在command中嵌入ulimit,maxconnections应设为软限制的70%~80%,且必须重启主进程生效。

Workerman 报 Too many open files,不是改一个地方就能解决的。它卡在系统、用户、进程、Workerman 自身四层限制叠加处,漏掉任何一层,maxConnections 都会静默失效。
查当前 Workerman 进程实际生效的 fd 限制
别信 ulimit -n 或配置文件,只看运行中进程的真实值:
- 先用
ps aux | grep start.php找到主进程 PID(通常是第一个非 daemonized 的 worker 进程) - 执行
cat /proc/<pid>/limits | grep "Max open files"</pid>—— 这行输出才是 Workerman 真正能用的上限 - 如果显示
1024 1024 files,说明所有上层配置都没生效,得从启动源头排查
systemd 启动时 ulimit 不生效的典型修复
Workerman 常用 systemctl start workerman 管理,但默认不加载 /etc/security/limits.conf。必须显式声明:
- 编辑服务文件:
sudo systemctl edit workerman.service - 填入:
[Service] LimitNOFILE=65535
- 保存后执行
sudo systemctl daemon-reload && sudo systemctl restart workerman - 重启后立刻再查
/proc/<pid>/limits</pid>,确认数值已更新
Workerman 自身 maxConnections 设置陷阱
$worker->maxConnections 是软性控制,它不会阻止系统级 fd 耗尽。设太高反而掩盖问题:
- 先用
lsof -p <pid> | wc -l</pid>统计当前 fd 占用数 - 把
maxConnections设为/proc/<pid>/limits</pid>中软限制值的 70%~80% - 比如系统给 65535,就设
$worker->maxConnections = 50000,留余量给定时器、日志、DNS 查询等 - 切勿设成 65535 —— 内核
net.core.somaxconn和net.ipv4.ip_local_port_range会成为新瓶颈
supervisord 启动时绕过 PAM limits 的补救
supervisord 不走 login shell 流程,/etc/security/limits.conf 完全无效:
- 在 supervisord 的
[program:workerman]段里,改command行: command=/bin/sh -c "ulimit -n 65535 && php start.php start -d"- 改完必须
supervisorctl reread && supervisorctl update && supervisorctl restart workerman - 否则
ulimit命令根本没被执行,Workerman 还是继承 supervisord 的默认 1024
最易被忽略的一点:所有修改都必须重启 Workerman 主进程,reload 不会重新读取 fd 限制 —— 因为限制只在 fork 子进程那一刻继承一次,之后不可更改。











