文件打开数
概述
Linux 系统对进程可打开的文件描述符数量有限制,当服务需要处理大量并发连接(如 Nginx、数据库、消息队列)时,默认限制可能成为性能瓶颈。本文档涵盖文件打开数限制的查看、临时修改和永久配置方法。
适用场景:
- 高并发 Web 服务器(Nginx、Tomcat)
- 数据库服务(MySQL、PostgreSQL、Redis)
- 消息队列(Kafka、RabbitMQ)
- 容器化部署环境
查看当前限制
查看系统级限制
# 查看系统最大文件打开数
cat /proc/sys/fs/file-max
# 查看系统已使用的文件描述符数量
cat /proc/sys/fs/file-nr
# 输出三个数字:已分配文件句柄数 | 已使用文件句柄数 | 文件句柄最大值查看用户级限制
# 查看当前会话的软限制(当前生效值)
ulimit -n
# 查看当前会话的硬限制(最大值)
ulimit -Hn查看特定进程的限制
# 查看指定进程的文件打开限制
cat /proc/<PID>/limits | grep "Max open files"
# 查看指定进程已打开的文件数
lsof -p <PID> | wc -l查看系统总体使用情况
# 查看系统所有进程打开的文件数
lsof | wc -l
# 查看进程打开文件数排序(Top 10)
lsof 2>/dev/null | awk '{print $2}' | sort | uniq -c | sort -rn | head -10修改文件打开数
临时修改(重启失效)
# 修改当前会话的用户级限制
ulimit -n 65536
# 修改系统级限制(立即生效)
echo 1048576 > /proc/sys/fs/file-max永久修改
1. 修改系统级配置(/etc/sysctl.conf)
# 编辑系统配置文件
sudo vi /etc/sysctl.conf
# 添加或修改以下参数
fs.file-max = 1048576
fs.nr_open = 1048576
# 使配置立即生效
sudo sysctl -p2. 修改用户级限制(/etc/security/limits.conf)
sudo vi /etc/security/limits.conf
# 针对所有用户
* soft nofile 65536
* hard nofile 131072
# 针对特定用户
username soft nofile 65536
username hard nofile 131072
# 针对 root 用户
root soft nofile 65536
root hard nofile 131072说明:
soft软限制:当前生效值,不能超过硬限制hard硬限制:最大值,需要 root 权限修改- 修改后需重新登录生效
3. 修改 PAM 模块配置(可选)
部分系统还需修改 PAM 配置使 limits.conf 生效:
# CentOS/Rocky
sudo vi /etc/pam.d/login
# 添加以下行(通常已存在)
session required pam_limits.so4. 修改 systemd 服务配置
重要:CentOS 7 / Rocky 9 中,systemd 管理的服务(如 Nginx、MySQL、Docker)不受 limits.conf 影响,需单独配置。
# 方式A:修改全局 systemd 配置
sudo vi /etc/systemd/system.conf
# 取消注释并修改
DefaultLimitNOFILE=65536
DefaultLimitNPROC=65536
# 方式B:针对特定服务修改
sudo vi /usr/lib/systemd/system/<service-name>.service
# 在 [Service] 部分添加
LimitNOFILE=65536
LimitNPROC=65536
# 重新加载 systemd 配置
sudo systemctl daemon-reload
sudo systemctl restart <service-name>5. Docker 容器配置
# 方式A:在 docker-compose.yaml 中配置
services:
app:
image: nginx
ulimits:
nofile:
soft: 65536
hard: 131072
# 方式B:在 Dockerfile 中配置
RUN ulimit -n 65536
# 方式C:运行容器时指定
docker run --ulimit nofile=65536:131072 -d nginx验证修改结果
# 1. 验证系统级限制
cat /proc/sys/fs/file-max
# 2. 验证用户级限制(需重新登录后验证)
ulimit -n
ulimit -Hn
# 3. 验证当前进程的限制
cat /proc/self/limits | grep "Max open files"
# 4. 验证特定服务进程的限制
sudo systemctl show <service-name> | grep LimitNOFILE
# 5. 验证 Docker 容器限制
docker exec <container-name> ulimit -n各场景配置速查表
| 场景 | 配置方式 | 生效方式 |
|---|---|---|
| 系统全局(所有用户) | /etc/sysctl.conf(fs.file-max) |
sysctl -p |
| 用户登录会话 | /etc/security/limits.conf |
重新登录 |
| SSH 会话 | /etc/pam.d/sshd + limits.conf |
重启 SSH 或重连 |
| systemd 服务 | /etc/systemd/system.conf 或服务文件的 LimitNOFILE |
systemctl daemon-reload + 重启服务 |
| Docker 容器 | ulimits 字段 |
重建容器 |
| 当前会话(临时) | ulimit -n 65536 |
会话退出后失效 |
常见问题与注意事项
修改 limits.conf 后不生效
- 确认 SSH 会话是否重新登录:
# 查看当前会话的 PAM 配置
cat /etc/pam.d/sshd | grep pam_limits- 检查是否受 systemd 用户实例限制:
# 查看用户登录时的限制
systemctl --user show | grep LimitNOFILE- 对于 SSH 登录用户,确保
/etc/ssh/sshd_config中未设置UsePAM no。
ulimit 设置后超过系统限制报错
确保 fs.file-max 和 fs.nr_open 设置的值大于 ulimit 设置的值:
# 查看系统最大值
cat /proc/sys/fs/file-max
cat /proc/sys/fs/nr_openNginx 提示 “too many open files”
# 确认 Nginx 服务限制
systemctl show nginx | grep LimitNOFILE
# 如未生效,在 nginx.conf 中添加
worker_rlimit_nofile 65536;
# 确保 systemd 服务配置了 LimitNOFILE
sudo vi /usr/lib/systemd/system/nginx.service
# 添加 LimitNOFILE=65536
sudo systemctl daemon-reload
sudo systemctl restart nginx