systemd服务的文件描述符限制不能靠/etc/security/limits.conf,必须在service单元中显式配置limitnofile,否则即使用户级设得再高,服务启动时仍继承systemd默认的1024;因其不经过pam登录流程,limits.conf根本不会被读取,真正起作用的是systemd fork时直接设置的rlimit。

Linux中systemd服务的文件描述符限制不能靠/etc/security/limits.conf,必须在service单元中显式配置LimitNOFILE,否则即使用户级设得再高,服务启动时仍继承systemd默认的1024。
为什么limits.conf对systemd服务无效
systemd管理的服务(如nginx、redis、mysql)不经过PAM登录流程,/etc/security/limits.conf根本不会被读取。你改完limits.conf后执行ulimit -n看到65535,但cat /proc/$(pidof nginx)/limits | grep "Max open files"仍显示1024——这就是典型的表现。
真正起作用的是systemd在fork进程时直接设置的rlimit,它只认自己unit文件里的LimitNOFILE。
正确配置LimitNOFILE的两种方式
推荐使用drop-in覆盖方式,避免直接修改原始unit文件(易被包管理器覆盖):
- 运行
sudo systemctl edit nginx.service,自动创建/etc/systemd/system/nginx.service.d/override.conf - 在文件中写入:
[Service] LimitNOFILE=65536
- 保存退出后执行:
sudo systemctl daemon-reload && sudo systemctl restart nginx
若需统一应用到所有服务,可编辑全局配置:sudo systemctl edit --system,然后在[Manager]段下添加DefaultLimitNOFILE=65536。
验证是否生效
不要只信ulimit -n,它只反映当前shell。查服务进程真实限制用:
-
systemctl show -p LimitNOFILE nginx.service→ 看unit配置值 -
cat /proc/$(pidof nginx)/limits | grep "Max open files"→ 看进程实际绑定值(最权威)
两者必须一致,且软硬限制都应达到预期(如65536:65536)。若不一致,说明没reload或配置位置错误。
注意内核总上限和硬限制边界
LimitNOFILE不能超过内核参数fs.file-max,更不能超出/proc/sys/fs/nr_open(系统允许单进程最大值)。
- 查当前上限:
cat /proc/sys/fs/nr_open - 若需调高(如设为1048576),先临时:
sudo sysctl -w fs.nr_open=1048576,再永久写入/etc/sysctl.conf - 确保
fs.file-max ≥ LimitNOFILE × 预估并发服务数,避免全局耗尽











