TCP连接高并发时修改 Socket 句柄数

编辑于:2019年10月28日
TCP连接高并发时修改 Socket 句柄数

有台服务器的磁盘经常被syslogdaemon.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认证登录用户的资源限制,它对systemdservice的资源限制不生效。

全局限制

对于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%左右,日志文件也不因疯狂的报错而变得超级大了,特写此文记录解决该问题的过程。

相关推荐