瑞瑞哥的博客

配置了ulimit,但是rc.local启动的进程的fd还是1024

配置了ulimit,但是rc.local启动的进程的fd还是1024

最近发现软路由有时候不稳定,最主要的表现就是罢工,我为软路由编写了健康检查脚本,但是也没发现什么内容。经过查看TcpRoute2的日志,发现提示too many open files才发现触发了单进程最大fd的限制。

问题是,我环境上在/etc/security/limits.conf中,配置了以下内容:

1
2
3
4
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535

登陆上环境,输入ulimit -n显示的也是65535,那么到底是怎么回事呢?

我去V2EX上提问的这个帖子中,我找到了答案:

我上面所述的方法,这种配置项类似环境变量,在用户登录后才会生效。一旦生效,启动的进程最大fd都是65535,哪怕后来又退出。

而我的TcpRoute2是用/etc/rc.local启动的,这个脚本是开机时候系统自动加载的,而这种场景下根本没有登录这个动作,TcpRoute2进程自然就无法被65535的最大fd加持。

帖子中热心的各位大大也给出了几种解决方案:

  • /etc/rc.local脚本里,通过prlimit -n xxx -p pid命令赋予最大fd

  • 这种方法我没试,估计是给系统调用的进程也带上65535的加持:

    1
    2
    3
    4
    5
    6
    {
    echo "* soft nproc 65535" > /etc/security/limits.d/90-nproc.conf
    echo "* hard nproc 65535" >> /etc/security/limits.d/90-nproc.conf
    echo "* soft nofile 65535" >> /etc/security/limits.d/90-nproc.conf
    echo "* hard nofile 65535" >> /etc/security/limits.d/90-nproc.conf
    }
  • sudo systemctl edit rc-local.service 然后

    1
    2
    [Service]
    LimitNOFILE=65536
  • 不再用rclocal启动服务,将服务用Systemd托管,然后设置LimitNOFILE

    经过考虑,我打算用最后一种方法,毕竟规范了很多。至于如何用Systemd托管服务器,可以看我的这个博客