“too many open files”错误源于linux五层文件句柄限制未对齐:需同步调优软限(ulimit -sn)、硬限(ulimit -hn)、用户级(/etc/security/limits.conf)、systemd级(limitnofile)和内核级(fs.file-max),并重新登录或重启服务生效。

FrankenPHP 1.1 本身不管理文件句柄数,它运行在 Linux 进程模型下,句柄限制完全由操作系统控制。出现 “Too many open files” 错误,不是 FrankenPHP 配置没改对,而是系统级限制没对齐——必须同步调好软限、硬限、用户配置、systemd 服务限制和内核总池子这五层。
查清当前瓶颈在哪一级
先执行三行命令快速定位:
- ulimit -Sn:看当前会话软限制(实际生效值)
- ulimit -Hn:看当前会话硬限制(软限不能超它)
- cat /proc/sys/fs/file-max:看内核允许的全局最大句柄数
如果前两者都是 1024,说明登录会话没放开;如果都是 65535 但 FrankenPHP 还报错,大概率是 systemd 没单独配,或 file-max 太小。
给 FrankenPHP 运行用户设永久用户级限制
编辑 /etc/security/limits.conf,追加两行(假设用 www-data 或 frankenphp 用户运行):
- www-data soft nofile 65535
- www-data hard nofile 65535
确认 /etc/pam.d/common-session(Ubuntu/Debian)或 /etc/pam.d/system-auth(RHEL/CentOS)里有未注释的这一行:
session required pam_limits.so
改完必须重新 SSH 登录(不是新开终端),再运行 ulimit -n 验证是否生效。
为 systemd 托管的 FrankenPHP 服务单独配 LimitNOFILE
/etc/security/limits.conf 对 systemd 服务无效。假设你用 frankenphp.service 启动:
- 运行 sudo systemctl edit frankenphp.service
- 填入:
[Service]
LimitNOFILE=65535
- 保存后执行:sudo systemctl daemon-reload && sudo systemctl restart frankenphp
- 验证:systemctl show frankenphp | grep LimitNOFILE 或 cat /proc/$(pgrep -f "frankenphp server")/limits | grep "Max open files"
别忘了扩大内核总句柄池
单个进程开到 65535 没用,如果内核总池子太小,照样失败。默认常为 32768:
- 临时调高:sudo sysctl -w fs.file-max=655350
- 永久生效:在 /etc/sysctl.conf 末尾加一行 fs.file-max=655350,再运行 sudo sysctl -p
- 检查是否够用:cat /proc/sys/fs/file-nr 返回三个数,中间那个是已分配未释放数,最后一个才是上限
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











