在现场 EasyCVR/EasyGBS 使用过程中,在接入大量设备后,程序运行会显示 too many open files。于是我们在 shell 中运行 ulimit –n 10240,可以成功,但是以服务运行,仍然是 too many open files。因此对 Linux 的 ulimit 进行针对性研究,解决该问题。
一、ulimit 命令
ulimit 用于 shell 启动进程所占用的资源。
查看系统限制数量 ulimit –n 查看系统显示数量(更详细) ulimit –a 设置系统显示数量 ulimit –n 1024 设置 open files 1024 查看 2056 进程的限制 cat /proc/2056/limits
查看某个进程打开的文件数 lsof -p 2056 | wc –l lsof -e /run/user/1000/gvfs -p 2056 | wc –l 查看进程打开的文件信息 lsof -c easydss lsof |wc -l cat /proc/15386/limits 1024-4096 go
全局设置 ulimit 数据
二、Soft Limit 和 Hard Limit 的区别
ulimit –n 默认查看的是软限制 ulimit –Hn 查看的是硬限制 ulimit –Sn 查看的是软限制 ulimit -n 的最大值是 $((2**20)) 也就是最大 1048576 多加个 1 都会报错 nofile 的 hard 绝对不允许超过 1048576,soft 随意,大不了最大1048576
三、服务和进程 ulimit 的区别
默认的软限制为 1024,硬限制为 4096 首先设置 ulimit –n 3000 以进程运行程序 ./tsingsee, 最终查看进程占用的 ulimit 进程为 5210 cat /proc/5210/limits
进程的最大连接数已经增加,为 3000 修改以服务运行,查看对应的 ulimit,仍然未 1024 4096
为什么以服务运行,ulimit 限制仍然为默认值?继续探索。 运行 cat /proc/5673/status 查看进程的状态,发现父进程的 pid 为 1:
查看对应的父进程为 systemd
以进程运行,pid为6943,查看对应的 6943 的父进程为 4286,查看 4286 的进程
结论: 服务的 ulimit 限制和进程的 ulimit 限制不是同一个地方设置的。 ulimit –n 1000 是临时设置 shell 的大小,网上的设置 /etc/security/limits.conf 中的 ulimit 大小,也是不会设置到服务程序中。
四、如何设置服务的 ulimit
CentOS 的服务是 systemd 程序启动的,其他操作系统是以另外的程序启动的。针对 CentOS 的配置如下: 有的操作系统是以 SysVinit 的方式启动服务的,对应的 ulimit 设置不同,需要针对性的探索。 以内核作为示范。首先内核安装的服务名为 TsingseeMediaServer 在 CentOS 为例,首先进入服务路径 /etc/system/system 里面会有一个 TsingseeMediaServer.service
vi TsingseeMediaServer.service 在 Service 选项添加一个一行 LimitNOFILE=5000
查看原始进程对应的 ulimit 限制 cat /proc/4043/limits
目前是 4000 个 ulimit。运行以下命令,让 5000 生效 systemctl daemon-reload 重启 tsingsee 服务,查看对应的进程的 ulimit
以上设置成功后,不会再出现 ulimit 的限制。