事情是這樣的,公司的項目使用了emq來作爲設備和服務器(Java開發的系統)的消息中間件,因爲是第一次用,出現了各種各樣奇奇怪怪的問題,大家理所當然的把鍋踢給了emq,最後都一一被事實打臉。毫無疑問,emq的守護神就是我啦,服務器應用的開發者。因爲在設備同事看來,emq和服務器是一體的,所以我就擔當起了守護emq的重任。
第一回合:
問題描述:
服務器應用偶爾出現了不斷重連問題,重啓電腦後再啓動emq,問題消失。服務器同事把矛頭直指emq的自動重連,自己重寫了emq重連,結果問題依然出現。
問題發現:
我在與設備調試的過程中,恰好也出現了掉線重連的問題,通過抓取發送的消息分析得知,原來發送的數據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);
}
這個問題的詳細分析,我的另一篇博客:https://blog.csdn.net/u012134942/article/details/90378570
第二回合:
問題描述 :
橫屏主機在emq向其發送固件升級消息後,出現掉線重連情況
問題校驗:
使用同樣的網絡環境、發送同樣的固件升級消息,豎屏主機沒有出現掉線重連情況,能正常接收固件升級消息。
問題分析:使用抓包工具,發現橫屏主機在接收到固件升級消息後,直接向emq 發送標識爲RST的TCP請求,至此橫屏主機與emq連接斷開。
抓包結果如下圖: 備註:橫屏主機ip: 10.106.41.10 服務器/emq ip:10.106.41.80
問題原因:至此定位爲設備端問題,設備端同事給出的原因是設備使用的安卓系統中斷問題。
第三回合:
問題描述:
設備又出現不斷掉線重連問題,而且這次不同,通過抓包看出是emq主動關閉TCP連接,矛頭直指emq。以前我一定比較淡定,這次有些懷疑了。
問題分析:通過抓包分析,設備建立tcp連接成功 ,沒有掉線,設備在150S左右發起新的連接,emq主動關閉上一個連接(正常操作,因爲同一個clientID,emq只允許一個TCP連接),150S左右後又發起一個新的連接,emq主動關閉上一個連接(屬正常操作),如此循環
問題解決:問題已經知道,怎麼解決也就不難了,調整下重連策略就好。
第四回合:
問題描述:設備連接上emq後掉線,抓包可以看到有大量的tcp retransmission。
問題分析:因爲出現大量的tcp retransmission,故懷疑是否網絡問題,將設備和emq放在同一交換機下,問題依然出現,如排除網絡問題。又因爲只有個別設備出現,故懷疑是否ip衝突,將設備下線,ping設備原有ip,依然能ping通,毫無疑問,ip衝突導致的問題。
抓包結果:
問題解決:將設備和辦公室使用電腦所在的網段分開。如設備使用:192.168.41.1~255 電腦:192.168.90.1~255
總結:我們分析問題時,不能先入爲主,總想着甩鍋,默認是別人的問題。要先分析自己的問題,做到有理有據。不然打臉真的很痛!
後話:抓包一直爽,一直抓包一直爽
抓包工具:Wireshark