在对 EMQX (https://www.emqx.io) 进行性能测试的过程中,当客户端连接达到一定数量以后,你可能会发现 EMQX 无法接入更多连接,并且在控制台或 /var/log/emqx/emqx.log.N
中出现以下错误日志:
[error] Accept error on 0.0.0.0:1883: EMFILE (Too many open files)
这说明目前 EMQX 打开的文件描述符数量达到了最大限制。当然,这个限制来自操作系统,而不是 EMQX,如果我们想要突破这个限制,就需要修改操作系统中相应的内核参数。
所以在本文中,我们将介绍如何修改内核参数来增大 EMQX 可以使用的文件描述符数量。
什么是文件描述符
文件描述符 是 Linux 系统内核为了高效管理被打开的文件而创建的索引。当我们使用以下函数调用打开一个文件时,fd 就是内核返回的文件描述符:
fd = open("example.txt", O_RDWR)
然后我们就可以通过这个 fd 对打开的文件进行各种读写操作,Linux 会根据 fd 索引到正确的文件。
不过,在 Linux 系统中,一切资源都可以看做是文件,除了我们常规理解中的文本文件、可执行文件这类普通文件,文件目录、硬件设备等也都可以看成是文件,这其中自然也包括了网络套接字(Network Socket)。
EMQX 作为一个 MQTT 服务器,每当有新的客户端接入,EMQX 都会创建一个新的套接字以和该客户端通信,相应地,这将占用一个文件描述符。
为了避免进程或无意或恶意打开过多的文件描述符,Linux 系统通常都会限制每个用户、每个进程能够打开的文件描述符数量。但默认的大小限制,显然难以满足有大量设备连接的 MQTT 服务器的需要。所以,修改内核参数成了我们必然的选择。
如何修改文件描述符的最大数量限制
在 Linux 系统中,一个进程最终可用的文件描述符的最大数量,受到多个内核参数或配置文件的影响。它们分别是:
/proc/sys/fs/file-max
/proc/sys/fs/file-max
中定义的值决定了整个系统可用的文件描述符的最大数量,我们可以通过以下命令来查看当前的限制:
cat /proc/sys/fs/file-max
如果当前值小于我们的期望值,我们可以运行以下命令来修改它:
echo <Number> > /proc/sys/fs/file-max
或者
sysctl -w fs.file-max = <Number>
上面这两个命令都可以让改动立即生效,但缺点是改动仅在当前会话有效,一旦用户注销或者系统重启,我们改