今天公司的 Kafka 突然挂了,上去检查状态如下:
systemctl status kafka
● kafka.service - Apache Kafka server (broker)
Loaded: loaded (/lib/systemd/system/kafka.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2021-02-06 05:33:47 CST; 2h 44min ago
Docs: http://kafka.apache.org/documentation.html
Process: 14657 ExecStop=/opt/apps/kafka/bin/kafka-server-stop.sh (code=exited, status=0/SUCCESS)
Process: 14671 ExecStart=/opt/apps/kafka/bin/kafka-server-start.sh /opt/apps/kafka/config/server.properties (code=exited, status=1/FAILURE)
Main PID: 14671 (code=exited, status=1/FAILURE)
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: at kafka.network.Acceptor.run(SocketServer.scala:601)
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: at java.lang.Thread.run(Thread.java:748)
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: [2021-02-06 05:33:45,124] ERROR Error while accepting connection (kafka.network.Acceptor)
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: java.io.IOException: Too many open files
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
Feb 06 05:33:45 ubuntu kafka-server-start.sh[14671]: at kafka.network.Acceptor.accept(SocketServer.scala:671)
Feb 06 05:33:47 ubuntu systemd[1]: kafka.service: Main process exited, code=exited, status=1/FAILURE
Feb 06 05:33:47 ubuntu systemd[1]: kafka.service: Failed with result 'exit-code'.
可以看到异常的那行是:
java.io.IOException: Too many open files
这个错我们肯定知道是啥原因,就是文件描述符限制太低了呀,查看一下:
$ ulimit -n
65535
诶?怎么好像不是很低的样子,那为啥报错?
检查发现这个 65535
的值来源于 /etc/profile
中的这样一行:
ulimit -SHn 65535
也就是说在每次创建一个会话时都会执行这一行来设置当前会话下的 open files
的值为 65535
,但是目前 kafka 依旧报错了。。说明这个值是不是对 kafka 进程没有生效呢?
答案是肯定的,我们可以通过 /proc
伪文件系统查看 kafka 进程当前读取到的 open files
值:
$ cat /proc/17833/limits | grep 'open files'
Max open files 4096 4096 files
上面的 17833
是 kafka 的进程号,通过这条命令可以实时看到 kafka 进程生效的 open files
值。
网上有很多常规的修改 open files
值的方法在这里都不合适,比如:
- 修改
/etc/security/limits.conf
,这种方式要重启系统,肯定是不适合正在运行的业务的; - 修改
/etc/profile
,这种方式就是我这原来使用的方式,它对通过 systemd 管理的进程是不生效的;
所以这里的解决办法是直接通过 systemd 来设置进程的 open files
限制,在 unit 文件中 Service
段下添加如下配置即可:
LimitNOFILE=65535
重启 kafka 服务,再次查看进程生效的 open files
值:
$ cat /proc/16326/limits | grep 'open files'
Max open files 65535 65535 files
OK 啦。。
评论区