emqx客户端连接频繁断连问题分析

2025-02-16  本文已影响0人  zcliu

一、背景

mqtt-sync-server 服务作为 mqtt 协议客户端,使用 Paho-MQTT 库连接 EMQX,上行负责订阅车端 tbox 上报的数据,下行负责下发指令至终端设备。
该服务目前线上部署了8个节点
1、10.0.0.217
2、10.0.0.230
3、10.0.0.226
4、192.168.0.209
5、192.168.0.287
6、192.168.0.232
7、192.168.0.200
8、10.0.0.220

二、问题

8个节点其中6个出现了与 emqx 频繁断连的错误。例如 10.0.0.226 自上次发布至今3个月,已发生 500 多万次重连


image.png

剩余2个节点192.168.0.209和 192.168.0.232则是正常的,没出现断连情况。

三、排查

1、日志对比

分析正常节点日志与频繁断连节点的日志


image.png image.png image.png

Paho-MQTT 库 Client 的线程名会带上客户端 ID


image.png

而我们服务自定义的clientId构造规则如下:


image.png

可以发现,正常节点的clientID是完整的且节点ip能正常获取。
而有问题的节点,clientID出现两种情况,
异常一:ip获取到的是127.0.0.1Linux/root/127.0.0.1
异常二:缺少ipLinux/root/

节点 clientID
192.168.0.09 Linux/root/192.168.0.209 正常
192.168.0.32 Linux/root/192.168.0.232 正常
192.168.0.87 Linux/root/127.0.0.1 异常一
192.168.0.00 Linux/root/127.0.0.1 异常一
10.0.0.26 Linux/root/ 异常二
10.0.0.30 Linux/root/ 异常二
10.0.0.17 Linux/root/ 异常二
10.0.0.20 Linux/root/ 异常二

2、EMQ Dashboard

image.png

EMQX后台的客户端监控页面,客户端ID以Linux开头的结果只有4个,期望应该是8个才对。
另外也会发现,ID Linux/root/127.0.0.1对应的ip地址不断在 192.168.0.287、192.168.0.200之间变换。
IDLinux/root/对应的ip地址则不断在10.0.0.226、10.0.0.230、10.0.0.217、10.0.0.220中变换。

四、原因分析

1、在构造clientID过程中,节点ip地址的获取方式是InetAddress.getLocalHost().getHostAddress()
这种方式依赖本机名去获取本机ip的,并不是一种可靠的方法。
因此会导致获取不到真实ip而导致出现重复的clientID。
2、使用同一客户端 ID 建立了多个连接,会导致已连接的设备断开连接。因为MQTT 规范只允许每个客户端 ID 有一个活动连接,因此当另一个节点使用同一客户端 ID 连接时,便会先踢掉先前的连接

五、解决方案

因为我们的服务在启动都会带上host.ipaddr这个参数,因此可以改为获取该参数值来得到ip


image.png

假设获取不到ip,可以使用当前时间戳作为兜底方案。


image.png

六、效果

可以看到客户端ID数量变为8个了,证明ID值已经是唯一了。


image.png

发布后,从服务日志显示没有重连的情况发生了


image.png
上一篇 下一篇

猜你喜欢

热点阅读