工做中的一次調試經驗

1 原因

  • 公司的設備偶爾掉線且掉線間隔時間不正確(32秒,應該30~31纔是正確的),可是不知道是什麼緣由
  • 使用python模擬設備,每10秒鐘發送mqtt消息
  • 另外啓動一個java客戶端,收集全部mqtt消息並存入mongodb
  • 最後比較真實設備與模擬,分析問題

2 基本架構

  • iot server(SpringBoot...)—— 部署在雲端
  • EMQ(開源物聯網MQTT消息服務)—— 部署在雲端
  • MQTT消息收集客戶端(SpringBoot mqtt mongo)—— 部署在雲端
  • 嵌入式設備(真實設備)—— 部署在本地網絡
  • python腳本(模擬設備)—— 部署在本地網絡

3 分析結果

  • 模擬設備的mqtt消息完整收集,一直處於在線狀態
  • 真實設備的mqtt消息少了一條,表明真實設備存在丟棄消息的狀況
  • iot server的設備在線處理邏輯存在1s的偏差,通過排查發現判斷邏輯有誤

4 iot server在線邏輯

  • 設備登陸或更新時,計數設置爲30s。
  • 秒定時器每次計數減1。
  • 當計數減到0,則判斷爲掉線。
boolean flag = i-- > 0; //這裏出錯了,應該先減小再判斷

5 Python

  • pip安裝paho包(http://www.eclipse.org/paho/)
$ pip install virtualenv
$ mkdir python-mqtt
$ cd python-mqtt
$ virtualenv --no-site-packages venv
$ source venv/Scripts/activate
$ pip install paho-mqtt
$ pip list
Package    Version
---------- -------
paho-mqtt  1.4.0
pip        18.0
setuptools 40.2.0
wheel      0.31.1
$ vi main.py
  • 代碼
import time
import paho.mqtt.client as mqtt
import logging
logging.basicConfig(level=logging.DEBUG)

# 官網這裏只有三個參數...,我直接複製下來一直報錯,修改成4個纔沒問題的。
def on_connect(mosq, obj, msg, rc):
    mqttc.subscribe("DEV/#", 0)
    print("rc: " + str(rc))


def on_message(mosq, obj, msg):
    print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))


def on_publish(mosq, obj, mid):
    print("mid: " + str(mid))


def on_subscribe(mosq, obj, mid, granted_qos):
    print("Subscribed: " + str(mid) + " " + str(granted_qos))


mqttc = mqtt.Client()
logger = logging.getLogger(__name__)
mqttc.enable_logger(logger)
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
mqttc.username_pw_set(
    "username", "password")
mqttc.connect("url", 1883, 60)
mqttc.loop_start()

while 1:
    (result, mid) = mqttc.publish("TOPIC/TEST", "", 0)
    time.sleep(10) # 每10秒發送1條

mqttc.loop_stop()
mqttc.disconnect()

6 MQTT消息收集客戶端

  • 收集mqtt消息,不須要啓動web服務,不須要加入web包且啓動不須要指定爲web項目
@SpringBootApplication
public class MqttMongoApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(MqttMongoApplication.class)
                .web(false) // 指定非web項目
                .build()
                .run(args);
    }
}

7 總結

  • 簡單代碼一不當心也可能出錯
  • python腳本編寫方便適合用於測試
相關文章
相關標籤/搜索