当前位置:首页 > 文章列表 > 文章 > linux > Linux 服务怎么限制文件描述符:LimitNOFILE、启动用户与日志检查

Linux 服务怎么限制文件描述符:LimitNOFILE、启动用户与日志检查

来源:17golang原创 2026-08-26 07:34:33 0浏览 收藏

线上服务出现“Too many open files”时,先别急着把机器级限制一口气调大。systemd 启动的服务有自己的进程上下文,当前终端里执行 ulimit -n 65535,并不会自动改变已经由 systemd 拉起的进程。更稳妥的做法是给目标 unit 写入 LimitNOFILE,再用进程实际限制和日志确认配置确实生效。

要点速览
  • LimitNOFILE 是 systemd 服务级配置,适合把文件描述符上限跟着 unit 管理。
  • 改完 drop-in 后必须执行 daemon-reload 和服务重启,并用 /proc/PID/limits 复核。
  • 上限不是越大越好,启动用户、连接池、日志轮转和内核资源要一起检查。
  • 发布前保留 systemctl cat、systemctl show 与 journalctl 的结果,回滚时只需移除 drop-in。

先区分当前 Shell 限制和服务进程限制

同一台机器上,下面两条命令可能给出不同答案:

ulimit -n
systemctl show order-api.service -p LimitNOFILE

第一条只反映当前 Shell 的资源限制;第二条查看 systemd 记录给 unit 的属性。真正处理请求的是服务进程,所以最终还要拿到 PID 检查 /proc/PID/limits。如果只改了登录用户的 shell 配置,服务重启后仍可能回到旧上限。

Linux 服务 LimitNOFILE 从默认限制到进程实际上限的对比

用 drop-in 给 order-api.service 设置上限

不要直接改发行版提供的 unit 文件,使用 drop-in 更容易审计和回滚:

sudo systemctl edit order-api.service

在打开的编辑器中写入:

[Service]
LimitNOFILE=65535

这里的数值要按连接数、日志文件、监听 socket 和程序自身打开的临时文件估算。一个服务如果有 2 万个长连接,再加上数据库连接池、文件缓存和运行时开销,65535 可能是合理的起点;如果只是小型定时任务,直接套用这个数字反而会掩盖句柄泄漏。

重载、重启后检查配置来源和实际值

配置保存后按固定顺序执行:

sudo systemctl daemon-reload
sudo systemctl restart order-api.service
systemctl is-active order-api.service
systemctl cat order-api.service
systemctl show order-api.service -p User -p LimitNOFILE -p FragmentPath

systemctl cat 用来确认 drop-in 确实被合并;systemctl show 则能看到 systemd 当前解析后的属性。这里别只看“active”,服务能启动不代表限制已经按预期传递给进程。

先取 PID,再检查进程上下文:

pid=$(systemctl show -p MainPID --value order-api.service)
ps -o pid,user,comm -p "$pid"
grep -i 'open files' "/proc/$pid/limits"
ls "/proc/$pid/fd" | wc -l

最后一条是当前打开句柄数的近似快照,不等于峰值。对长期运行的服务,建议把它和进程指标、连接池指标一起观察,避免仅凭一次检查下结论。

Linux 服务重启后通过 systemctl、proc limits 和 journal 日志复核文件描述符限制

启动用户和日志权限也要一起验收

服务的 User= 决定了它能打开哪些目录和日志文件。LimitNOFILE 配置正确,但启动用户无法访问日志目录,仍然会在启动后反复报错。发布检查至少要记录下面几项:

检查项命令通过标准
配置来源systemctl cat order-api.service能看到目标 drop-in
运行用户systemctl show ... -p User与目录权限设计一致
进程上限/proc/PID/limitsSoft/Hard 值符合预期
启动日志journalctl -u order-api.service -b无权限或句柄相关错误

查看本次启动日志时,优先使用:

journalctl -u order-api.service -b --no-pager -n 100
journalctl -u order-api.service -b -p warning..alert --no-pager

如果日志里出现 EMFILE、Permission denied 或某个路径无法创建,先确认是描述符耗尽、目录权限还是应用自己的资源泄漏。不要把所有错误都归因于 LimitNOFILE。

生产环境的数值边界与回滚方法

建议先在一台实例上改动,压测或回放一段与生产接近的连接流量,观察句柄数量是否持续上涨。若句柄数接近上限,优先查连接关闭、文件句柄泄漏和日志轮转;提高上限只能延后故障。

回滚时删除 drop-in 中的两行配置,再重载并重启:

sudo systemctl revert order-api.service
sudo systemctl daemon-reload
sudo systemctl restart order-api.service
systemctl show order-api.service -p LimitNOFILE

如果 unit 里还有其他人工 drop-in,不要直接使用 revert 覆盖它们;先用 systemctl cat 确认文件来源,再删除本次创建的片段。回滚也要检查服务状态和最近一轮日志。

常见问题

改了 /etc/security/limits.conf,systemd 服务会跟着变吗?

不能直接假设会变。该文件主要影响登录会话,systemd unit 应使用自身的资源限制配置,并以进程实际值为准。

LimitNOFILE 设置成 unlimited 可以吗?

不建议把它当作默认修复。无限制会放大句柄泄漏和内核资源消耗,应该先按连接模型设定明确上限。

systemctl show 已经是 65535,为什么应用仍报 EMFILE?

可能是服务运行后确实耗尽了上限,也可能是应用或依赖进程没有正确关闭文件。继续检查当前 FD 数量、连接池和日志轮转,而不是只看 unit 属性。

重启后限制又恢复了怎么办?

用 systemctl cat 检查 drop-in 是否位于正确目录,再确认是否执行过 daemon-reload。如果配置由部署工具管理,还要检查下一次发布是否覆盖了该文件。

发布前的最小检查清单

把 systemctl cat、systemctl show、/proc/PID/limits 和 journalctl -u ... -b 四类结果留档,再进行下一台实例的变更。这样即使问题出在应用资源泄漏,也能快速证明 systemd 的配置是否真正生效。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go iter.Pull 怎么安全消费迭代器:停止时机、资源释放与 goroutine 泄漏排查Go iter.Pull 怎么安全消费迭代器:停止时机、资源释放与 goroutine 泄漏排查
上一篇
Go iter.Pull 怎么安全消费迭代器:停止时机、资源释放与 goroutine 泄漏排查
Go http.Request.Clone 和 WithContext 有什么区别:请求体、Header 与重试边界
下一篇
Go http.Request.Clone 和 WithContext 有什么区别:请求体、Header 与重试边界
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    409次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    487次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    495次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    443次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    271次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码