导读:本期聚焦于书生创作的《Ubuntu系统如何调整文件描述符限制?ulimit配置方法详解》,敬请观看详情。程序报出Too many open files错误怎么办?这通常是Linux文件描述符达到上限导致的。本文围绕Ubuntu系统,完整讲解文件描述符的概念与默认限制的查看方式,重点介绍通过ulimit命令临时修改限制、编辑limits.conf实现永久生效、配置systemd服务的LimitNOFILE参数等三种常用方案,并说明各方法的作用范围、生效条件以及验证技巧。无论你是部署高并发服务、运行数据库,还是排查连接数受限问题,都能从中找到适合自己的配置思路。

在Ubuntu上部署Nginx、Redis、数据库或者高并发的网络服务时,经常会在日志里看到"Too many open files"这样的报错。这个错误的根源是进程打开的文件描述符数量达到了系统上限。Linux把每个打开的文件、网络套接字、管道都视为一个文件描述符,默认的1024个限制对于现代服务来说往往不够用。本文详细介绍如何在Ubuntu中查看并调整这个限制,覆盖临时修改和永久配置两种场景。

Ubuntu系统如何调整文件描述符限制?ulimit配置方法详解

一、文件描述符是什么,如何查看当前限制

文件描述符(File Descriptor,简称fd)是Linux内核为每个打开的文件、套接字、管道等资源分配的一个非负整数。进程每打开一个文件或建立一条TCP连接,就会消耗一个fd。可以用一个简单的比喻理解:fd就像餐厅的桌号,桌号数量固定,客人多了就得加桌子,否则后来的客人只能被拒绝。

Ubuntu中查看限制最常用的是ulimit -n命令,-n参数专门显示当前shell环境下打开文件数量的软限制。软限制是内核实际执行的限制值,与之对应的还有硬限制,用ulimit -Hn查看。硬限制是软限制能调整到的天花板,普通用户只能把软限制调低或调高到硬限制以内,只有root用户才能提高硬限制。

除了ulimit,还可以直接查看内核级限制和某个进程的实际使用情况:

# 查看当前软限制和硬限制
ulimit -Sn
ulimit -Hn

# 查看系统级的fd总数上限
cat /proc/sys/fs/file-max

# 查看指定进程的fd限制(以PID为1234为例)
cat /proc/1234/limits | grep "open files"

# 查看系统当前已分配的fd数量
cat /proc/sys/fs/file-nr

其中/proc/sys/fs/file-nr输出三列数值,分别表示已分配的fd数、已分配但未使用的fd数、以及系统最大值。如果第一列逼近第三列,说明整个系统的fd资源已经吃紧,这时候只调整单进程限制是不够的,还需要提高系统级上限。

二、使用ulimit临时调整限制

最快速的调整方式是在当前shell会话中执行ulimit命令。比如想把软限制提升到65535,直接执行:

# 普通用户可在硬限制范围内调高软限制
ulimit -n 65535

# root用户可以同时提高硬限制(unlimited表示不限制)
ulimit -Hn unlimited
ulimit -n 65535

# 修改后验证
ulimit -n

需要注意,这种方式只对当前shell以及由它启动的子进程生效。关掉终端或重启系统后,设置就会失效,回到默认值。对于临时调试或者手动启动一个服务来说够用,但不适合生产环境的长期部署。

另一个常见的坑是把ulimit命令写进脚本却没生效。原因是ulimit是shell内置命令,影响的是执行它的那个shell进程。如果你在脚本里设置ulimit后用su或sudo切换用户再启动服务,新起的进程可能继承不到这个设置。正确的做法是把ulimit语句放在启动服务的同一个shell脚本里,且在启动命令之前执行。

三、修改limits.conf实现永久生效

要让限制在用户登录后持久生效,标准做法是编辑/etc/security/limits.conf文件。这个文件由PAM模块读取,格式为每行四列:域(用户名或组名)、类型(soft或hard)、项目和值。

# 编辑配置文件
sudo vim /etc/security/limits.conf

# 在文件末尾追加以下内容
# 给所有用户设置软限制和硬限制
* soft nofile 65535
* hard nofile 65535

# 也可以只针对特定用户,比如www-data
www-data soft nofile 65535
www-data hard nofile 65535

# 通配符*不包含root,root需要单独写一行
root soft nofile 65535
root hard nofile 65535

修改保存后,重新登录(SSH需要断开重连,不能只执行source)即可生效,再用ulimit -n验证。这里有个容易忽略的细节:通配符*并不包含root用户,所以root要单独配置一行,否则以root身份登录时仍然是默认值。

limits.conf依赖PAM认证流程,因此它只对通过登录会话启动的进程有效。由systemd管理的服务(Ubuntu 16.04之后绝大多数服务都由systemd接管)并不会读取这个文件,这就引出了下一节的配置方式。

四、为systemd服务单独配置LimitNOFILE

systemd托管的服务有自己独立的资源限制体系,需要在服务的unit文件中设置。以Nginx为例,先执行systemctl cat nginx找到它的service文件路径,然后创建一个override配置,避免直接修改原文件导致升级时被覆盖:

# 创建override配置(目录会自动创建)
sudo systemctl edit nginx

# 在打开的编辑器中写入以下内容,保存退出
[Service]
LimitNOFILE=65535

# 重新加载配置并重启服务
sudo systemctl daemon-reload
sudo systemctl restart nginx

# 验证:先找到nginx worker进程的PID
ps -ef | grep nginx
cat /proc/上面的PID/limits | grep "open files"

执行systemctl edit后,实际生成的文件位于/etc/systemd/system/nginx.service.d/override.conf,这个机制的好处是升级软件包时你的自定义配置不会被冲掉。如果想给所有systemd服务设置全局默认值,可以编辑/etc/systemd/system.conf和/etc/systemd/user.conf,把其中的DefaultLimitNOFILE取消注释并设为想要的值,然后重启系统。

验证服务是否真的拿到了新限制,不要只看配置文件,一定要通过/proc/进程PID/limits查看实际运行值。有些服务自身还有内部的fd上限(比如Nginx的worker_rlimit_nofile指令、Redis的maxclients参数),系统限制调大之后别忘了同步检查应用层的配置,两边取较小值才是最终生效的限制。

五、调整系统级上限与注意事项

除了单进程限制,内核层面的fs.file-max决定了整个系统能打开的fd总数。在非常高的并发场景下需要一并调整:

# 临时修改,立即生效
sudo sysctl -w fs.file-max=2097152

# 永久生效:写入sysctl配置
echo "fs.file-max = 2097152" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

设置时建议遵循一个原则:file-max应远大于所有进程的nofile限制之和乘以一个合理系数,因为系统中每个进程的基础fd开销也要占用全局额度。数值并不是越大越好,每个fd都会占用内核内存,盲目调到几十亿没有任何收益,反而浪费资源。

最后梳理一下排查思路:遇到fd耗尽问题时,先用ls /proc/进程PID/fd | wc -l统计进程实际打开了多少fd,判断是资源泄漏还是确实需要更高配额。如果是代码忘记关闭文件或连接,调大限制只是延缓问题爆发,根治还得从代码层面入手。确认确实需要提升后,再按照临时ulimit、永久limits.conf、systemd服务LimitNOFILE这三个层次依次配置,并用/proc下的limits文件逐项验证,确保配置真正落地。

Ubuntu文件描述符ulimit配置Linux系统优化修改时间:2026-09-09 23:36:56

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0909/53666.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。