如何解决 Linux 系统文件描述符耗尽的问题

在Linux系统中,文件描述符(File Descriptor, FD)是操作系统管理打开文件、套接字、管道等资源的抽象标识。当进程或系统耗尽文件描述符时,会导致服务崩溃、连接失败等严重问题。以下是详细的排查和解决方案:


**一、问题确认**

1. **检查当前文件描述符使用情况**

```bash

查看系统已使用的FD数量

cat /proc/sys/fs/file-nr

输出示例:7864 0 9223372036854775807

分别表示:已分配FD数 | 未使用FD数 | 系统最大FD限制

查看各进程的FD使用量(按使用量排序)

lsof -n | awk '{print $2}' | sort | uniq -c | sort -nr | head

```

2. **确认系统级限制**

```bash

查看系统全局限制

cat /proc/sys/fs/file-max

临时修改限制(重启失效)

sysctl -w fs.file-max=1000000

```

3. **检查用户级限制**

```bash

查看当前用户的软/硬限制

ulimit -n # 软限制

ulimit -Hn # 硬限制

```


**二、临时解决方案**

1. **增加进程的FD限制**

```bash

临时提高当前会话的限制(仅对当前Shell有效)

ulimit -n 65535

```

2. **重启受影响的服务**

```bash

找到高FD占用的进程并重启

systemctl restart <service_name>

```


**三、永久解决方案**

1. **修改系统全局限制**

```bash

编辑/etc/sysctl.conf,增加以下行

fs.file-max = 1000000

生效配置

sysctl -p

```

2. **修改用户级限制**

```bash

编辑/etc/security/limits.conf,针对用户或组设置

* soft nofile 65535 # 所有用户软限制

* hard nofile 100000 # 所有用户硬限制

特定用户示例

www-data soft nofile 50000

www-data hard nofile 100000

```

3. **修改服务单元配置(Systemd)**

```bash

编辑服务配置文件(如nginx)

sudo systemctl edit nginx.service

添加以下内容:

Service

LimitNOFILE=100000

重载并重启服务

systemctl daemon-reload

systemctl restart nginx

```


**四、深入排查与优化**

1. **定位FD泄漏的进程**

```bash

统计进程FD使用量

ps aux | awk '{print 2}' \| xargs -I {} sh -c 'echo {} (ls /proc/{}/fd/ 2>/dev/null | wc -l)' | sort -k2 -nr | head

```

2. **分析FD类型**

```bash

查看某进程打开的FD详情(替换<PID>)

ls -l /proc/<PID>/fd

检查是否有异常(如大量未关闭的socket或文件)

```

3. **代码层面修复**

  • **检查应用程序**:确保文件、套接字、数据库连接等资源使用后正确关闭。

  • **使用工具检测**:

  • `valgrind`(C/C++内存和FD泄漏检测)

  • `lsof -p <PID>`(实时监控进程FD)

4. **内核参数调优(高并发场景)**

```bash

增加TCP连接相关限制(避免socket耗尽)

echo "net.ipv4.tcp_max_tw_buckets = 200000" >> /etc/sysctl.conf

echo "net.core.somaxconn = 65535" >> /etc/sysctl.conf

sysctl -p

```


**五、预防措施**

  1. **监控与告警**
  • 使用Prometheus+Grafana监控`file-nr`指标。

  • 设置告警规则(如FD使用率超过80%时触发)。

  1. **定期维护**
  • 日志轮转(避免日志文件过多占用FD)。

  • 定期重启长期运行的服务(如数据库、Web服务器)。

  1. **压力测试**
  • 使用工具(如`ab`、`wrk`)模拟高并发场景,提前发现FD瓶颈。

**六、常见场景示例**

**案例1:Nginx服务器FD耗尽**

```bash

1. 修改Nginx配置

worker_rlimit_nofile 100000;

events {

worker_connections 50000;

}

2. 调整Systemd限制(见上文)

```

**案例2:MySQL连接泄漏**

```sql

-- 查看当前连接数

SHOW STATUS LIKE 'Threads_connected';

-- 优化连接池配置(如JDBC的maxActive参数)

```


通过以上步骤,可彻底解决文件描述符耗尽问题。关键点在于:

  1. **合理设置系统/用户级限制**

  2. **定位并修复资源泄漏**

  3. **建立长期监控机制**。

相关推荐
泷羽Sec-pp44 分钟前
DC-9靶机通关笔记
linux·运维·网络·笔记·docker·容器
时序数据说1 小时前
通过Linux系统服务管理IoTDB集群的高效方法
大数据·linux·运维·数据库·开源·时序数据库·iotdb
大唐锦绣2 小时前
Docker下Gogs设置Webhook推送Spug,踩坑记录与解决方案
运维·docker·容器·gogs
SamHou02 小时前
从 UEFI 启动到双系统——记一次双系统 Linux 分区迁移
linux·windows·grub
阳光男孩啊2 小时前
五、Linux系统之vim编辑器
linux·运维·编辑器·vim
鱼嘻2 小时前
线程邮箱框架与示例
linux·c语言·开发语言·算法·php
小茬粥2 小时前
COLT_CMDB_linux_userInfo_20250508.sh修复历史脚本输出指标信息中userName与输出信息不一致问题
linux·运维·服务器
生信圆桌3 小时前
生信服务器如何安装cellranger|生信服务器安装软件|单细胞测序软件安装
运维·服务器
未来之窗软件服务3 小时前
智慧农业运维平台养殖—传感器管理监控设计—仙盟创梦IDE
运维·css·ide·仙盟创梦ide
weixin_436525073 小时前
芋道框架 账号未登录、租户标识未传递
java·linux·服务器