有台服务器的磁盘经常被syslog
和daemon.log
两个文件撑满,CPU负载也经常飚满。查看这两个文件,几乎全都是/core/transport/internet/tcp: failed to accepted raw connections > accept tcp [::]:18919: accept4: too many open files
的报错。最后通过修改socket句柄数的限制解决了这个问题。
当前socket句柄数限制
当前系统限制的最高socket句柄数是多少?通过Xshell 连接服务器,执行如下命令ulimit -n
,返回结果是1024
,说明服务器目前单线程socket句柄数最高只有这些。
目前所有进程各自使用了多少句柄数呢?执行查询命令:(如果提示没有安装lsof
,先运行yum install lsof
安装lsof
,再重新运行查询命令)
lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more
大吃一惊!仅一个进程号1950
的程序就使用了20332
个句柄数,远远超过了1024
的限制,怪不得疯狂的报错。(左侧一列是句柄数,右侧一列是进程号)
进程号1950
的程序是什么?执行命令查看一下ps -aef|grep 1950
,从图片可以看出导致问题的元凶是V2Ray配置文件。
修改最大句柄数的限制
默认值1024确实太低,需要提高句柄数的上限。在修改上限前,我们看看这台服务器从硬件性能上来讲,最高能支持的句柄数是多少。执行cat /proc/sys/fs/file-max
返回是上限是198749
首先打开/etc/security/limits.conf
在文件末尾添加如下代码保存。
* soft nofile 102400 * hard nofile 102400
然后打开/etc/profile
在文件末尾添加
ulimit -SHn 102400
上面添加的内容中数字部分是数量上限,可以根据自己的需要修改。保存修改,执行服务器重启命令 shutdown -r now
。重新连接服务器执行查询命令 ulimit -n
,可以看到返回的结果已经是刚才修改的 102400
了,说明生效了。
但是监控服务器发现问题依旧???
systemd service 句柄数限制
后来才知道在CentOS 7/RHEL 7
的系统中,使用Systemd
替代了之前的SysV
,因此 /etc/security/limits.conf
的配置,只适用于通过PAM认证登录用户的资源限制,它对systemd
的service
的资源限制不生效。
全局限制
对于systemd service
的资源限制,全局的配置放在文件/etc/systemd/system.conf
和/etc/systemd/user.conf
,同时也会加载两个对应的目录中的所有.conf
文件/etc/systemd/system.conf.d/*.conf
和/etc/systemd/user.conf.d/*.conf
其中system.conf
是系统实例使用的user.conf
用户实例使用的,一般的evice
使用system.conf
中的配置即可;此外注意,systemd.conf.d/*.conf
中配置会覆盖 system.conf
打开/etc/systemd/system.conf
在文末添加如下内容,数字部分是数量上限,可以根据自己的需要修改,保存已修改的 system.conf
重启系统生效。
DefaultLimitCORE=infinity DefaultLimitNOFILE=102400 DefaultLimitNPROC=102400
单个限制
针对单个Service
也可以设置,以这次遇到报错的程序V2Ray为例,打开 /etc/systemd/system/v2ray.service
在文中的[Service]
下方,添加如下内容
LimitCORE=infinity LimitNOFILE=102400 LimitNPROC=102400
运行如下命令使修复生效。
sudo systemctl daemon-reload sudo systemctl restart v2ray.service
观察服务器状态,终于恢复正常了,CPU从100%降到20%左右,日志文件也不因疯狂的报错而变得超级大了,特写此文记录解决该问题的过程。