Linux 文件句柄(ulimit)限制导致程序崩溃的解决

上周我在部署一个高并发的网络服务时,遇到了一个让人头疼的问题——服务运行一段时间后就会莫名其妙崩溃,日志里满是 “Too many open files” 的错误。经过排查,发现是 Linux 系统的文件句柄限制在作祟。今天我就把这次踩坑经历和解决方案整理出来,希望能帮到遇到类似问题的朋友。
什么是文件句柄限制?
在 Linux 系统中,每个进程能够打开的文件数量是有限制的。这个限制包括普通文件、网络连接、管道等各种类型的文件描述符。当程序打开的文件数量超过这个限制时,系统就会拒绝新的文件操作,导致程序异常。
如何查看当前限制
首先,我们需要确认当前的限制设置。可以通过以下命令查看:
# 查看当前用户的文件句柄限制
ulimit -n
# 查看系统全局限制
cat /proc/sys/fs/file-max
# 查看特定进程的限制
cat /proc/<pid>/limits | grep "Max open files"
在实际排查中,我发现默认的 1024 个文件句柄对于高并发服务来说远远不够,这就是导致程序崩溃的根本原因。
临时修改限制
如果需要快速解决问题,可以临时修改限制。这种方法在系统重启后会失效,适合紧急处理:
# 将当前会话的文件句柄数提升到 65535
ulimit -n 65535
# 验证修改是否生效
ulimit -n
需要注意的是,这种方法只对当前会话有效,而且普通用户不能设置超过硬限制的值。
永久修改限制
要永久解决这个问题,需要修改系统配置文件。我推荐以下两种方法:
# 方法一:修改 /etc/security/limits.conf
# 在文件末尾添加以下内容
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf
# 方法二:修改 systemd 服务的限制(如果使用 systemd)
# 在服务的配置文件中添加:
# LimitNOFILE=65535
修改完成后需要重新登录或者重启系统才能生效。我建议同时使用这两种方法,确保万无一失。
验证修改结果
修改配置后,一定要验证是否生效:
# 重新登录后检查
ulimit -n
# 检查系统全局限制
cat /proc/sys/fs/file-max
# 对于运行中的服务,重启后检查进程限制
cat /proc/$(pidof your-service)/limits | grep "Max open files"
监控文件句柄使用情况
为了避免问题再次发生,建议定期监控文件句柄的使用情况:
# 查看系统总的文件句柄使用情况
cat /proc/sys/fs/file-nr
# 查看特定进程打开的文件
lsof -p <pid> | wc -l
# 实时监控文件句柄使用
watch -n 1 'cat /proc/sys/fs/file-nr'
经验总结
通过这次经历,我总结了几个重要的经验:
- 在部署高并发服务前,一定要先检查系统的文件句柄限制
- 生产环境建议将限制设置为 65535 或更高
- 定期监控文件句柄使用情况,及时发现潜在问题
- 对于容器化部署,还需要注意容器级别的限制
希望这篇文章能帮你避免我踩过的坑。如果你在实践过程中遇到其他问题,欢迎在评论区交流讨论!


太实用了!刚部署服务就遇到这问题,救星来了!