事情是这样的,公司的项目使用了emqx来作为设备和服务器(Java开发的系统)的消息中间件,因为是第一次用,出现了各种各样奇奇怪怪的问题,大家理所当然的把锅踢给了emqx,最后都一一被事实打脸。
备注:emqx版本 v4.0.7
第一回合:
问题描述:
服务器应用偶尔出现了不断重连问题,重启电脑后再启动emqx,问题消失。服务器同事把矛头直指emq的自动重连,自己重写了emqx重连,结果问题依然出现。
问题发现:
我在与设备调试的过程中,恰好也出现了掉线重连的问题,通过抓取发送的消息分析得知,原来发送的数据json格式有误,解析时出错,而这个错误没有被捕获,导致了emq掉线。
解决方案:往该主题发送空的保留消息 替换掉之前的错误消息
try {
revDataMap = JSONConext.getResultMap(data);
}catch (Exception e){
/**
* emq不断重连问题修复
* 原因:收到保留的错误消息
* 解决方案:往该主题发送空的保留消息 替换掉之前的错误消息
* retained 为true时 保留
*
*/
byte[] bytes = new byte[0];
LoginClientManage.getSiteServerClient().getMqttClient().publish(topic, bytes, ParCfg.getInstance().getDefalutQoS(), true);
logger.error("错误保留消息:"+message.toString());
logger.error("接收到错误保留消息,执行清空该保留消息:"+e);
}
这个问题的详细分析,我的另一篇博客:emq 不断掉线重连_MK 乘风破浪~的博客-CSDN博客_emq 客户端掉线
第二回合:
问题描述 :
横屏主机在emqx向其发送固件升级消息后,出现掉线重连情况
问题校验:
使用同样的网络环境、发送同样的固件升级消息,竖屏主机没有出现掉线重连情况,能正常接收固件升级消息。
问题分析:使用抓包工具,发现横屏主机在接收到固件升级消息后,直接向emqx 发送标识为RST的TCP请求,至此横屏主机与emqx连接断开。
抓包结果如下图: 备注:横屏主机ip: 10.106.41.10 服务器/emq ip:10.106.41.80
问题原因:至此定位为设备端问题,设备端同事给出的原因是设备使用的安卓系统中断问题。
第三回合:
问题描述:
设备又出现不断掉线重连问题,而且这次不同,通过抓包看出是emqx主动关闭TCP连接,矛头直指emqx。以前我一定比较淡定,这次有些怀疑了。
问题分析:通过抓包分析,设备建立tcp连接成功 ,没有掉线,设备在150S左右发起新的连接,emqx主动关闭上一个连接(正常操作,因为同一个clientID,emqx只允许一个TCP连接),150S左右后又发起一个新的连接,emq主动关闭上一个连接(属正常操作),如此循环
问题原因:经过上面分析,可以得出是因为设备代码中的emqx重连策略出现的bug导致的。
问题解决:问题已经知道,怎么解决也就不难了,调整下重连策略就好。
第四回合:
问题描述:设备连接上emqx后掉线,抓包可以看到有大量的tcp retransmission。
问题分析:因为出现大量的tcp retransmission,故怀疑是否网络问题,将设备和emqx放在同一交换机下,问题依然出现,如排除网络问题。又因为只有个别设备出现,故怀疑是否ip冲突,将设备下线,ping设备原有ip,依然能ping通,毫无疑问,ip冲突导致的问题。
抓包结果:
问题解决:将设备和办公室使用电脑所在的网段分开。如设备使用:192.168.41.1~255 电脑:192.168.90.1~255
总结:我们分析问题时,不能先入为主,总想着甩锅,默认是别人的问题。要先分析自己的问题,做到有理有据。不然打脸真的很痛!
后话:抓包一直爽,一直抓包一直爽
抓包工具:Wireshark