1. 程式人生 > >那些年用EMQ踩過的坑

那些年用EMQ踩過的坑

前提

語言用的是Java,包是org.eclipse.paho.client.mqttv3這個,MQ是EMQ。

坑一

客戶端ID相同,導致互相擠下線

場景

公司有很多場景用到MQTT,比如移動端、Java後臺、前端JS、流水線C#程式、各類物聯網硬體Python指令碼等等

很多同事使用的時候,如果進行連線的clientID有衝突的話,會導致已經連線的客戶端斷開連線,而這個時候如果客戶端的回撥裡面做了斷線重連處理的話,就會變成2個客戶端一直在斷線重連...斷線重連...斷線重連...

解決方案:

既然問題是客戶端ID相同,那就讓客戶端ID不相同即可。

比如給客戶端ID加UUID字尾,或者加時間戳字尾之類的,只要能確保不重複即可。

//客戶端
MqttClient testClient = new MqttClient("主題名稱","testClient_"+UUID.randomUUID().toString());
//配置
MqttConnectOptions options = new MqttConnectOptions();
options = new MqttConnectOptions();
options.setCleanSession(true);//設定清除會話資訊  
options.setUserName("使用者名稱");//設定使用者名稱
options.setPassword("密碼".toCharArray());//設定密碼
testClient.setCallback(new TestCallback());//回撥
testClient.connect(options);//連線

坑二

回撥類報錯引發的客戶端斷線

場景

當我們的客戶端訂閱了某個主題,該主題收到訊息後,就會進到messageArrived方法。

public void messageArrived(String topic, MqttMessage message) throws Exception {
    // subscribe後得到的訊息會執行到這裡面
    // 時間格式轉換
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println("接收訊息時間 : " + sdf.format(new Date()));
    System.out.println("接收訊息主題 : " + topic);
    System.out.println("接收訊息Qos : " + message.getQos());
    System.out.println("接收訊息內容 : " + new String(message.getPayload()));
        
}

一般我們傳送和接收到的訊息都是JSON格式的字串,然後會在這個方法裡面做業務邏輯處理。

當我們收到的訊息內容不符合預期的格式時,而我們又未做相應的處理時,就會報錯丟擲異常,從而導致接收到該訊息的客戶端斷線。

如果只是普通的程式碼邏輯問題,只需要打個斷點看看具體問題具體分析,然後處理即可。

如果是因為傳送訊息方使用了Retained,導致的一訂閱收到訊息即報錯,觸發重連後重新訂閱又報錯的死迴圈的話。

有可能是在18083控制檯傳送的測試資料,預設被勾選了Retained

也可能是程式碼裡面傳送訊息設定了Retained

//第四個引數retained
testClient.publish(topic, payload, qos, retained);

解決方案:

用任一客戶端往有問題的主題傳送一條空訊息,並設定Retained為true,即可清除該主題所保留的最後一條設定了Retained的異常訊息。

testClient.publish("有問題的主題", "".getBytes(), 0, true);

坑三

傳送的訊息內容太長,導致客戶端斷線

場景

客戶端往某個主題傳送訊息,訊息內容太長導致一執行傳送操作,客戶端就掉線。

原因是EMQ預設的訊息長度是64K(65536位元組),一旦超過就會出問題。

解決方案:

根據版本的不同,找到對應的配置檔案,修改對應的配置即可,最高為256MB

如1.x版本的EMQ則在安裝目錄的/emqttd/etc/emqttd.config修改其中的

如2.x版本的EMQ則在安裝目錄的/emqttd/etc/emqttd.conf修改其中的

也可能在安裝目錄的/emqttd/etc/emq.conf修改其中的

然後重啟EMQ即可。

坑四

未完。。。待編輯。。。

注:僅供自己學習,記錄問題和參考,若有帶來誤解和不便請見諒,共勉!