Saltstack 最大打开文件数问题之奇怪的 8192
哈喽大家好,我是咸鱼。
今天分享一个在压测过程中遇到的问题,当时排查这个问题费了我们好大的劲,所以我觉得有必要写一篇文章来记录一下。
问题出现
周末在进行压测的时候,测试和开发的同事反映压测有问题,请求打到 A 服务上被拒绝了。
我们登录服务器查看 A 服务的日志,发现频繁地报 Too many open files 错误,可以看到压测的时候该进程要处理大量的 socket,导致打开的文件描述符数量已经达到了操作系统允许的最大限制,因此无法再打开更多的文件。
java.io.IOException: Too many open files...
既然是系统资源相关的问题,我们先 ulimit -n 看一下系统中进程能够使用的最大文件描述符是多少个:
[root@localhost ~]# ulimit -n
100000
为了稳妥起见,我们还查看了 /etc/security/limits.conf 文件的内容:
[root@localhost ~]# cat /etc/security/limits.conf
* soft nofile 100000
* hard nofile 100000
可以看到系统限制进程能够最多打开 100000 个文件(我们在服务器初始化的时候设置的值)。但是压测的量还没上去,A 服务上的进程打开文件数就超过了 10 万个吗?
查看一下这个进程打开了多少个文件:
[root@localhost ~]# cat /proc/<该进程的 PID>/fd | wc -l
8295
我们发现该进程才打开了八千多个文件,远远没有达到系统限制的 100000。
接着看下这个进程的文件描述符数量限制,通过 /proc/<Java 进程的 PID>/limits 文件来查看
[root@localhost ~]# cat /proc/<该进程的 PID>/limits
...
Max open files 8192 8192 files
...
奇怪,按理说每个进程的文件描述符使用限制应该是 100000,但是这里却显示只有 8192,说明系统层面的资源限制在这个进程上没有生效,而且这个 8192 是怎么来的,为什么是 8192 ?
我们重启了一下这个服务,发现重启之后该进程的资源限制生效了,Max open files 数量变成了 100000 !
# 重启服务
[root@localhost ~]# sh spring-boot.sh restart# 查看该进程的文件描述符数量限制
[root@localhost ~]# cat /proc/<该进程的 PID>/limits
...
Max open files 100000 100000 files
...
定位问题
发现了这个现象之后,我们接着排查了其他的服务,发现服务进程的 Max open files 数量都是 8192,而系统设置的却是 100000。
如果我们一旦手动重启服务,进程的 Max open files 数就变成了系统设置的 100000。
我们在初始化服务器的时候,已经修改了进程的最大打开文件数为 100000,如果配置没有生效,那也应该是系统的默认值 1024 ,而不是 8192。
就在一筹莫展的时候,我们注意到了一个细微差别:由于线上服务器较多,平时我们都是通过 Saltstack 来管理服务(包括服务的启动重启停止),而今天是在终端上重启服务的,所以会不会跟 Saltstack 相关?
然后我们为了验证执行了下面的步骤:
- 找到一台服务器,先查看了上面进程的最大打开文件数,发现是 8192。
- 手动重启一下服务,发现进程的最大打开文件数变成 100000
- 我们在 salt-master 上远程重启这台服务,发现进程的最大打开文件数变成了 8192。
接着我们在 salt-master 上远程执行 ulimit -a 命令
[root@salt-master ~]# salt <服务器 ip> cmd.run 'ulimit -a'
...
open files (-n) 8192
...
排查到这里,终于有点柳暗花明的感觉了,我们看一下这台服务器上 salt-minion 进程的资源限制:
[root@localhost ~]# cat /proc/<salt-minion 进程的 PID>/limits
...
Max open files 8192 8192 files
...
又因为 salt-minion 是通过 systemctl 来管理的,所以我们在这台服务器上查看 salt-minion 的服务注册文件:
[root@localhost ~]# cat /usr/lib/systemd/system/salt-minion.service
[Unit]
...[Service]
KillMode=process
Type=notify
NotifyAccess=all
LimitNOFILE=8192
ExecStart=/usr/bin/salt-minion[Install]
...
果然,奇怪的 8192 出现在了这两处地方!
关于 Linux 下 Ulimit 资源限制
首先,/etc/security/limits.conf 文件中的配置对于通过 PAM 认证登录的用户资源限制是有效的。
也就是说,登陆了系统的用户,无论是交互式登录还是非交互式登录,其资源限制都会受到 limits.conf 中的配置影响。
但是,在 CentOS 7/RHEL 7 等系统中,默认采用 Systemd 作为 init 系统,取代了之前的 SysV init,对于 Systemd 启动的服务(例如使用 systemctl 启动的服务),limits.conf 中的配置对其资源限制是不生效的。

这是因为 Systemd 会忽略 limits.conf 中的设置,而是使用自己的资源管理机制。
这里补充一下,在 CenOS 5/6 中,/etc/security/limits.conf 和 /etc/security/limits.d 中的配置文件是为通过PAM登录的用户设置资源限制的。这些限制在用户登录时由PAM模块加载并应用(什么是 PAM ,你可以简单理解为一般情况登陆了终端都会加载 PAM 模块),因此仅在用户会话期间生效。

所以就会出现某进程在机器重启后资源限制设置与 /etc/security/limits.conf 和 limits.d 下的文件不一致的问题,可能是因为进程是在系统启动时自动启动的,而不是通过用户登录而启动的。因此不会受到 PAM 模块加载的影响。在这种情况下,进程的资源限制可能受到系统级别的默认限制或其他配置文件的影响。
我们对某一台 CentOS 6 的机器进行重启后,发现上面设置了开机自启动的进程的资源限制都发生了变化(变成了系统设置的默认值),一旦我们手动重启,资源限制则设置成了跟 /etc/security/limits.conf 文件设置的一致
对于一些设置了开机自启动的进程,如果在机器重启后保持资源限制不发生变化,可以在进程的启动脚本里加上关于资源限制设置的命令,比如说
ulimit -SHn 10000
所以在 Systemd 中,可以通过在服务单元文件中设置 Limit* 选项来控制服务的资源限制,比如限制进程的最大打开文件数 LimitNOFILE 为 8192。
LimitNOFILE=8192
当我们通过 Salt-master 来管理远程服务器的时候(服务器上面往往部署了 Salt-minion),即 Salt-master 发送命令给 Salt-minion 时,通常情况下,Salt-minion 会直接在自身进程中执行相应的操作。
如果是通过 Salt-minion 来启动一个进程,这个进程则会继承 Salt-minion 的资源限制配置。
这也就是为什么通过 salt-minion 管理的进程的最大打开文件数都是 8192,因为 salt-minion 的最大打开文件数就是 8192。
解决问题
既然知道了这是关于 systemd services 的资源限制相关的问题,那就好解决了。
- 针对所有的 service :
配置 systemd services 的资源限制可以在全局范围内进行。这些配置文件分别位于 /etc/systemd/system.conf 和 /etc/systemd/user.conf。
system.conf 文件适用于系统级实例,而 user.conf 文件适用于用户级实例。一般建议在 system.conf 中配置服务的资源限制,但如果在 /etc/systemd/system.conf 文件中修改配置,则需要重启系统才能使更改生效。
此外,还可以通过在 /etc/systemd/system.conf.d/ 和 /etc/systemd/user.conf.d/ 目录中放置 .conf 文件进行配置。
需要注意的是,system.conf.d/*.conf 中的配置会覆盖 system.conf 中的配置。
如果你打算修改所有通过 systemctl 管理的服务进程的资源限制(比如修改最大文件打开数量)
那可以修改/etc/systemd/system.conf
[root@localhost ~]# vim /etc/systemd/system.conf
DefaultLimitNOFILE=100000
- 针对单个 service:
这次案例的解决方法就是要修改单个 service (即 salt-minion)的资源限制配置。
# 修改 salt-minion 的 service 文件,改成和系统一样的资源限制配置
[root@localhost ~]# cat /usr/lib/systemd/system/salt-minion.service
...
[Service]
LimitNOFILE=100000
...
修改完之后别忘了重启。
[root@localhost ~]# systemctl daemon-reload[root@localhost ~]# systemctl restart salt-minion.service
相关文章:
Saltstack 最大打开文件数问题之奇怪的 8192
哈喽大家好,我是咸鱼。 今天分享一个在压测过程中遇到的问题,当时排查这个问题费了我们好大的劲,所以我觉得有必要写一篇文章来记录一下。 问题出现 周末在进行压测的时候,测试和开发的同事反映压测有问题,请求打到…...
Appium Inspector 展示设备当前页面
定位元素需要使用appium inspector,之前每次都是从登录页开始,后来发现连接设备的时候只需要去掉appPackage、appActivity即可。 { "platformName": "Android", "platformVersion": "6", "deviceNa…...
PyQt:实现菜单栏的点击拖动效果
一、整体步骤 1.设计UI文件 2.调用显示 3.效果展示 二、设计UI文件 1.添加 Scroll Area控件,作为菜单栏的布置区域 2.设置 Scroll Area控件的属性 3.Scroll Area控件内放置 按钮控件 组成菜单栏 此处,放置了需要了6个按钮,并设置按钮的固…...
力扣--并查集547.省份数量
思路分析: 首先定义变量 fa 用于记录并查集,以及城市数量 n。定义了并查集的两个函数,find 用于查找节点的根节点,togother 用于合并两个节点所在的集合。在公共函数 findCircleNum 中,初始化并查集,然后遍…...
leetcode35-Search Insert Position
排序数组搜索某个元素,这种思维一定要往二分法上靠 public class searchInsertPosition{public static void main(String[] args) {int arr[] {1,3,5,6};System.out.println(getIndex(arr,2));}public static int getIndex(int[] arr,int target) {int start 0;i…...
API 接口渗透测试
1 API 接口介绍 1.1 RPC(远程过程调用) 远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无…...
oracle 19c单机版本补丁升级
文章目录 一、补丁包概述二、备份opatch三、替换高版本opatch四、打DB补丁1、关闭数据库2、关闭监听3、解压补丁4、冲突检测5、补丁空间检查6、执行补丁升级7、将更新内容加载到数据库8、最后查看数据库版本9、卸载补丁包 一、补丁包概述 补丁升级包 链接:https://…...
推荐系统的未来:大模型驱动的个性化推荐技术与挑战
推荐系统的未来:大模型驱动的个性化推荐技术与挑战 1. 背景介绍 推荐系统是现代互联网服务中不可或缺的一部分,它通过分析用户的历史行为和偏好,为用户提供个性化的内容推荐,从而提高用户体验和满意度。随着大数据、机器学习和人…...
Allegro许可管理工具
在数字化时代,软件许可管理成为企业面临的挑战之一。如何确保软件的合规使用、优化资源配置并降低运营成本是企业关注的焦点。Allegro许可管理工具作为一款强大的管理工具,为企业提供了全面、高效的解决方案。本文将深入探讨Allegro许可管理工具的卓越实…...
React函数组件Hook
问题: 相对于类组件, 函数组件的编码更简单, 效率也更高, 但函数组件不能有state (旧版) 解决: React 16.8版本设计了一套新的语法来让函数组件也可以有state Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 Hook也叫钩子…...
【FinalShell】远程连接 Linux 工具 FinalShell 的使用:查看 AI 语言大模型对话实时日志
一、查看 APP 实时 AI 问答消息的 websocket 类型日志 (1)Linux 模板命令配置 Linux 命令:查看 AI 语言大模型结合向量数据库的实时问答消息日志 ① 测试环境 FinalShell 命令模板 【Linux 命令标题】[Test_APP] today tail:webs…...
ARM Coresight 系列文章 11.1 -- CoreSight Cortex-M33 CTI 详细介绍】
请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 CTI 的工作原理CTI 主要特点CTI的使用场景CTI 的工作原理 CTI 允许不同的调试和追踪组件之间基于特定事件进行交互。例如,当一个断点被命中时,CTI 可以用来触发内存的追踪捕捉或者外部仪器的行为,反之亦然。这种…...
Linux常用操作命令(清单快查版)
Linux常用操作命令,今日先给出快查清单,后续出带命令参数及不同OS的区别语法的相关示例 1. 文件与目录操作 命令描述ls列出目录内容cd切换目录pwd显示当前工作目录mkdir创建目录rmdir删除空目录cp复制文件或目录mv移动或重命名文件或目录rm删除文件或目…...
[C语言]结构体、位段、枚举常量、联合体
目录 结构体 结构体的使用方法 结构体所占用的大小 位段 位段的使用方法 位段所占用的大小 枚举常量 枚举常量的使用方法 枚举常量的优势 联合体 联合体的使用方法 结构体 结构体的使用方法 结构体是一些值的集合,我们可以定义一个结构体,里…...
LangChain核心模块 Retrieval——文档加载器
Retrieval 许多LLM申请需要用户的特定数据,这些数据不属于模型训练集的一部分,实现这一目标的主要方法是RAG(检索增强生成),在这个过程中,将检索外部数据,然后在执行生成步骤时将其传递给LLM。 LangChain 提供…...
力扣爆刷第104天之CodeTop100五连刷6-10
力扣爆刷第104天之CodeTop100五连刷6-10 文章目录 力扣爆刷第104天之CodeTop100五连刷6-10一、15. 三数之和二、53. 最大子数组和三、912. 排序数组四、21. 合并两个有序链表五、1. 两数之和 一、15. 三数之和 题目链接:https://leetcode.cn/problems/3sum/descrip…...
Docker操作基础命令
注意:以下命令在特权模式下进行会更有效! 进入特权模式 sudo -ssudo su拉取镜像 sudo docker pull [镜像名] # sudo docker pull baiduxlab/sgx-rust:2004-1.1.3进入容器 端口开启服务: sudo docker start 3df9bf5dbd0c进入容器…...
穿越地心:3D可视化技术带你领略地球内部奇观
在广袤无垠的宇宙中,地球是一颗充满生机与奥秘的蓝色星球。我们每天都生活在这颗星球上,感受着它的温暖与恩赐,却往往忽略了它深邃的内部世界。 想象一下,你能够穿越时空,深入地球的核心,亲眼目睹那些亿万年…...
蓝桥杯刷题_day1_回文数_水仙花数_进制转换
文章目录 特殊的回文数回文数水仙花数十六进制转八进制_n次 特殊的回文数 问题描述 123321是一个非常特殊的数,它从左边读和从右边读是一样的。 输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。 解题…...
jmeter接口导入方式
curl直接导入 1、操作页面后,F12查看接口,右击接口-copy-copy as cURL 2、jmeter 工具-import from cURL,粘贴上面复制的curl 根据接口文档导入 1、接口文档示例如下: Path: /api/jobs/xps/exec Method…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
WEB3全栈开发——面试专业技能点P4数据库
一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库,基于 mysql 库改进而来,具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点: 支持 Promise / async-await…...
