源MQTT調(diào)試工具實(shí)測(cè):MQTTX、MQTT Explorer與MQTT CLI使用指南)
做物聯(lián)網(wǎng)開(kāi)發(fā)這些年我?guī)缀跆焯於荚诟?MQTT 協(xié)議打交道。設(shè)備離線了、指令沒(méi)回執(zhí)、某個(gè)主題的數(shù)據(jù)格式不對(duì)問(wèn)題一大半都能在調(diào)試工具里現(xiàn)出原形。最近項(xiàng)目里又用到幾款開(kāi)源 MQTT 調(diào)試工具實(shí)測(cè)下來(lái)確實(shí)好用今天專門(mén)抽時(shí)間整理成一篇使用筆記分享給同樣被 MQTT 調(diào)試折磨過(guò)的朋友。無(wú)論你是剛?cè)腴T(mén)物聯(lián)網(wǎng)的新手還是已經(jīng)在嵌入式、智能家居、工業(yè)采集領(lǐng)域摸爬滾打多年的老手這三款工具都能幫你省下大量抓包分析的時(shí)間值得人手一份。我這次要聊的是 MQTTX、MQTT Explorer、MQTT CLI 這三款開(kāi)源工具。它們的定位完全不同一個(gè)像是“聊天軟件”專門(mén)處理收發(fā)消息一個(gè)像是“文件樹(shù)瀏覽器”專門(mén)把主題層級(jí)攤開(kāi)給人看還有一個(gè)是“命令行利器”用來(lái)寫(xiě)自動(dòng)化測(cè)試腳本。三者組合起來(lái)基本覆蓋了我日常調(diào)試 MQTT 的絕大多數(shù)場(chǎng)景。1. 為什么你需要一套趁手的 MQTT 調(diào)試工具1.1 調(diào)試 MQTT 到底在“調(diào)”什么很多人一聽(tīng)到“調(diào)試 MQTT”第一反應(yīng)就是“不就是訂閱一個(gè)主題、發(fā)一條消息嗎”。但真正做過(guò)量產(chǎn)設(shè)備接入的人都知道MQTT 調(diào)試遠(yuǎn)不只是“能連上、能說(shuō)話”這么簡(jiǎn)單。它涉及連接鑒權(quán)、主題設(shè)計(jì)、QoS 語(yǔ)義、保留消息、遺囑消息、心跳保活、會(huì)話恢復(fù)等一系列細(xì)枝末節(jié)任何一個(gè)環(huán)節(jié)出問(wèn)題表現(xiàn)都是“消息發(fā)不出來(lái)”或者“訂閱收不到”。舉個(gè)例子設(shè)備端上報(bào)數(shù)據(jù)用的是publish云平臺(tái)或者 App 端用subscribe來(lái)收。如果設(shè)備端的 Client ID 跟其他設(shè)備重了Broker 會(huì)把舊連接踢掉表現(xiàn)就是設(shè)備一會(huì)兒在線一會(huì)兒離線如果發(fā)布端用的是 QoS 0而訂閱端期望 QoS 1消息在網(wǎng)絡(luò)抖動(dòng)時(shí)可能直接丟再比如你訂閱了/dev/#但設(shè)備實(shí)際發(fā)布到了/dev/device01/data通配符中間多了一層那也一樣收不到。這些現(xiàn)象光憑肉眼看日志基本看不出來(lái)必須有一個(gè)趁手的調(diào)試工具把“連接狀態(tài)、主題關(guān)系、消息內(nèi)容”同時(shí)擺在你面前才行。所以我認(rèn)為調(diào)試 MQTT 本質(zhì)上是在調(diào)五樣?xùn)|西第一Broker 地址、端口、TLS 配置是否正確第二Client ID、用戶名密碼是否被 Broker 接受第三主題字符串是否完全匹配通配符是否寫(xiě)對(duì)第四QoS 和 Retain 標(biāo)志是否符合業(yè)務(wù)預(yù)期第五Payload 內(nèi)容是否被上下游正確解析。只要這五樣都通了設(shè)備接入才算真正跑通。而這三款工具恰好能在不同層面幫你驗(yàn)證這五樣?xùn)|西。1.2 選型思路三款工具如何各司其職最開(kāi)始我其實(shí)只用一款命令行工具后來(lái)發(fā)現(xiàn)不同的調(diào)試場(chǎng)景對(duì)工具的要求完全不同。日常聯(lián)調(diào)時(shí)我需要一個(gè)圖形界面能快速創(chuàng)建連接、輸入主題、點(diǎn)按鈕發(fā)消息最好還能看到消息時(shí)間線這時(shí)候 MQTTX 最合適。等到設(shè)備數(shù)量多一些、主題層級(jí)復(fù)雜起來(lái)我又需要一種“全局視角”把整個(gè) Topic 樹(shù)可視化展開(kāi)看看那臺(tái)設(shè)備到底有沒(méi)有在某個(gè)子主題上報(bào)數(shù)據(jù)這時(shí)候 MQTT Explorer 的價(jià)值就體現(xiàn)出來(lái)了。而到了寫(xiě)回歸測(cè)試、做持續(xù)集成、或者跑到服務(wù)器上用 SSH 一臺(tái)裸機(jī)抓問(wèn)題時(shí)GUI 反而礙事一條命令完成發(fā)布訂閱的模式才是剛需這時(shí)候 MQTT CLI 出手。這三款都是純正的開(kāi)源項(xiàng)目代碼托管在 GitHub 上社區(qū)活躍度都很高。MQTTX 由 EMQX 團(tuán)隊(duì)維護(hù)適合中文用戶文檔也全MQTT Explorer 是個(gè)人開(kāi)發(fā)者作品界面簡(jiǎn)潔克制MQTT CLI 是 HiveMQ 出品的命令行客戶端理念是“把所有能力都藏進(jìn)參數(shù)里”。我在下表里把它們的核心差異列了出來(lái)方便你按需選擇工具主要形態(tài)核心優(yōu)勢(shì)最適用的場(chǎng)景開(kāi)源地址關(guān)鍵詞MQTTX桌面 GUI收發(fā)消息直觀、多連接管理、腳本模擬日常手動(dòng)聯(lián)調(diào)、新人上手emqx/MQTTXMQTT Explorer桌面 GUI主題樹(shù)可視化、歷史數(shù)據(jù)記錄觀察主題結(jié)構(gòu)、排查數(shù)據(jù)是否上報(bào)thomasnordquist/MQTT-ExplorerMQTT CLI命令行參數(shù)全面、易集成腳本自動(dòng)化測(cè)試、遠(yuǎn)程服務(wù)器排查hivemq/mqtt-cli如果說(shuō)我對(duì)選型有什么心得那就是千萬(wàn)別指望一款工具包打天下。圖形化工具適合“人肉排查”命令行工具適合“機(jī)器執(zhí)行”。平時(shí)我電腦上三款都裝著哪個(gè)順手用哪個(gè)。2. MQTTX最像“聊天軟件”的桌面客戶端2.1 核心功能與特色MQTTX 是我用得最多的桌面客戶端界面設(shè)計(jì)得非常直觀。它把 MQTT 的發(fā)布和訂閱做成了類似聊天軟件的形式左邊是消息列表輸入框在下面你發(fā)出去的消息和訂閱到的消息會(huì)按時(shí)間順序混排在一起。這種交互設(shè)計(jì)的優(yōu)點(diǎn)是你一眼就能看出“上一條消息是什么時(shí)候發(fā)的”“對(duì)方有沒(méi)有回復(fù)”調(diào)試請(qǐng)求和響應(yīng)的對(duì)應(yīng)關(guān)系時(shí)特別省力。MQTTX 的核心功能遠(yuǎn)不止發(fā)收消息這么簡(jiǎn)單。它支持同時(shí)創(chuàng)建多個(gè)連接每個(gè)連接可以綁定不同的 Broker、不同的 Client ID、不同的鑒權(quán)信息。這一點(diǎn)在做多設(shè)備模擬時(shí)很有用——我可以同時(shí)模擬一個(gè)網(wǎng)關(guān)和三個(gè)子設(shè)備分別連接到 Broker然后觀察它們之間通過(guò)主題交互的數(shù)據(jù)流。它還支持常見(jiàn)的 Payload 格式切換包括 Plaintext、JSON、Hex、Base64遇到二進(jìn)制幀數(shù)據(jù)時(shí)可以直接看 Hex不用自己手動(dòng)轉(zhuǎn)碼。更讓我滿意的是內(nèi)置腳本功能可以編寫(xiě) JavaScript 腳本對(duì)收到的消息做一些自動(dòng)處理比如模擬設(shè)備端收到下行指令后自動(dòng)回復(fù)一條狀態(tài)消息這比一個(gè)個(gè)手動(dòng)點(diǎn)按鈕高效太多了。MQTTX 是跨平臺(tái)的Windows、macOS、Linux 都有安裝包同時(shí)還支持 WebSocket 連接方式。如果你的 Broker 開(kāi)了 WebSocket 端口用 MQTTX 也能直接連這對(duì)于前端調(diào)試物聯(lián)網(wǎng)應(yīng)用特別方便。它解決了我在實(shí)際項(xiàng)目里最頭疼的一個(gè)問(wèn)題連不連得上、消息有沒(méi)有到全都在一個(gè)界面里看明白不用再反復(fù)看 Broker 端日志。2.2 安裝與常用操作流程安裝 MQTTX 沒(méi)什么難度去 GitHub Release 頁(yè)面下載對(duì)應(yīng)系統(tǒng)的安裝包就行也可以到官網(wǎng)下載。我一般建議直接下載綠色免安裝版本解壓就能跑。首次打開(kāi)后主界面會(huì)提示你添加連接。我習(xí)慣把連接配置分成三類場(chǎng)景。第一類是本地開(kāi)發(fā)環(huán)境Broker 地址寫(xiě)127.0.0.1端口通常是1883不需要用戶名密碼適合直接連本機(jī)跑的 EMQX、Mosquitto 或 NanoMQ。第二類是測(cè)試環(huán)境Broker 地址寫(xiě)服務(wù)器 IP端口可能是1883或8883如果開(kāi)了 TLS就要在 MQTTX 里勾選 SSL/TLS 選項(xiàng)并加載 CA 證書(shū)。第三類是公共測(cè)試 Broker比如broker.emqx.io或test.mosquitto.org這類環(huán)境適合臨時(shí)驗(yàn)證工具本身是否正常不適合傳輸生產(chǎn)數(shù)據(jù)。配置完連接后點(diǎn)“連接”按鈕。如果連接成功界面變綠你就能看到 Broker 返回的 CONNACK 信息。接下來(lái)在訂閱主題輸入框里填#點(diǎn)擊訂閱你就能看到當(dāng)前 Broker 上所有已發(fā)布的消息。如果是第一次玩我建議你先自己給自己發(fā)一條主題填test/helloPayload 填{msg:hello mqtt}QoS 選 1點(diǎn)發(fā)送。如果你訂閱了#這條消息馬上就會(huì)出現(xiàn)在列表里。這個(gè)過(guò)程雖然簡(jiǎn)單但能把 MQTT 最基本的“發(fā)布-訂閱”模型直觀地跑一遍。提示調(diào)試階段我建議把 Retain 標(biāo)志保留為 false除非你明確想測(cè)試保留消息。否則 Broker 上會(huì)殘留一堆舊消息下次訂閱時(shí)突然刷出來(lái)一片很容易誤導(dǎo)判斷。3. MQTT Explorer把 MQTT 主題變成“文件樹(shù)”3.1 為什么推薦 MQTT Explorer如果說(shuō) MQTTX 是為“收發(fā)消息”設(shè)計(jì)的那 MQTT Explorer 就是為“理解主題結(jié)構(gòu)”設(shè)計(jì)的。它會(huì)把 Broker 上目前存在的所有主題動(dòng)態(tài)展開(kāi)成一棵可折疊的樹(shù)狀結(jié)構(gòu)。比如你設(shè)備上報(bào)到factory/line1/machine01/temperature樹(shù)狀結(jié)構(gòu)就會(huì)逐級(jí)展開(kāi)為factory→line1→machine01→temperature每一層都可以點(diǎn)擊查看當(dāng)前值。這種展示方式讓我一下子就能看出整個(gè)設(shè)備網(wǎng)絡(luò)的主題規(guī)劃是否合理、哪些設(shè)備掛了、哪些數(shù)據(jù)在更新。MQTT Explorer 另一個(gè)讓我印象深刻的地方是它會(huì)保留歷史記錄。當(dāng)我展開(kāi)一個(gè)主題節(jié)點(diǎn)時(shí)不僅能看到當(dāng)前最新的一條消息還能看到一段時(shí)間內(nèi)的歷史變化曲線。對(duì)于傳感器數(shù)據(jù)調(diào)試來(lái)說(shuō)這相當(dāng)于內(nèi)置了一個(gè)簡(jiǎn)易報(bào)表工具不用再額外連數(shù)據(jù)庫(kù)就直接能看到某個(gè)溫度值在過(guò)去 5 分鐘里的大致波動(dòng)趨勢(shì)排查“設(shè)備有沒(méi)有周期性上報(bào)”這種問(wèn)題非常直接。它的界面非??酥茮](méi)有太多花哨的功能核心就是“把 Broker 上正在流動(dòng)的消息結(jié)構(gòu)可視化”。它同樣支持連接多個(gè) Broker支持用戶名密碼、TLS 配置也可以直接發(fā)消息到一個(gè)主題。雖然發(fā)消息的手感不如 MQTTX 那么順暢但在需要邊看結(jié)構(gòu)邊發(fā)指令的場(chǎng)景下也夠用。尤其適合做智能家居項(xiàng)目的人家里幾十個(gè)設(shè)備、上百個(gè)主題用 MQTTX 一條一條手動(dòng)訂閱效率極低用 MQTT Explorer 打開(kāi)一棵主題樹(shù)哪個(gè)設(shè)備在線、哪個(gè)設(shè)備已經(jīng)離線一目了然。3.2 主題可視化的實(shí)戰(zhàn)價(jià)值我舉個(gè)之前做過(guò)的智能大棚項(xiàng)目例子。大棚里有幾十個(gè)傳感器節(jié)點(diǎn)每個(gè)節(jié)點(diǎn)上報(bào)空氣溫濕度、土壤濕度、光照強(qiáng)度主題格式是shed/area/node_id/metric。調(diào)試期間有一個(gè)節(jié)點(diǎn)的土壤濕度數(shù)據(jù)一直不刷新。用 MQTTX 訂閱#后消息刷得飛快根本來(lái)不及定位是哪條消息異常。這時(shí)候我換成 MQTT Explorer 打開(kāi)主題樹(shù)展開(kāi)shed→area→ 各node_id看到大部分葉子節(jié)點(diǎn)下面都有更新只有那臺(tái)異常節(jié)點(diǎn)對(duì)應(yīng)的葉子節(jié)點(diǎn)沒(méi)有新的消息出現(xiàn)。我立刻斷定問(wèn)題出在設(shè)備端而不是 Broker 端于是直接到現(xiàn)場(chǎng)看設(shè)備日志果然是傳感器 I2C 總線偶爾掉線導(dǎo)致上報(bào)線程掛死。這個(gè)案例很好地說(shuō)明了主題可視化的實(shí)戰(zhàn)價(jià)值它把“消息內(nèi)容是否正確”和“消息是否真的存在”這兩件事分開(kāi)了。MQTTX 專注于前者M(jìn)QTT Explorer 擅長(zhǎng)后者。在調(diào)試復(fù)雜系統(tǒng)時(shí)先用 MQTT Explorer 找到“異常缺失”的主題再用 MQTTX 去精確定位某一條消息的 Payload是我屢試不爽的組合拳。順帶說(shuō)一句MQTT Explorer 也可以當(dāng)一個(gè)主題設(shè)計(jì)審查看板。如果你剛搭好一套主題規(guī)范拿它連上 Broker 跑一天第二天去看主題樹(shù)如果某個(gè)分支出現(xiàn)了亂七八糟的節(jié)點(diǎn)那說(shuō)明設(shè)備端代碼里肯定有人把主題寫(xiě)錯(cuò)了。這種“用調(diào)試工具反推設(shè)計(jì)缺陷”的方式比單純看代碼走查要直觀得多。4. MQTT CLI腳本自動(dòng)化與線上排查利器4.1 命令行工具使用場(chǎng)景MQTT CLI 和前面兩款圖形界面工具完全走了另一條路它沒(méi)有界面所有的操作都通過(guò)命令完成。最開(kāi)始我總覺(jué)得“圖形界面都這么強(qiáng)了命令行還有什么用”直到我在服務(wù)器上排查問(wèn)題才意識(shí)到它的價(jià)值。生產(chǎn)環(huán)境的 Broker 往往部署在遠(yuǎn)程 Linux 服務(wù)器上沒(méi)有圖形桌面這時(shí)候想用一個(gè) GUI 客戶端去調(diào)試要么得做端口轉(zhuǎn)發(fā)把服務(wù)暴露到本地要么得在服務(wù)器上裝桌面環(huán)境都很麻煩。MQTT CLI 直接通過(guò) SSH 登錄服務(wù)器后就能運(yùn)行輕量、無(wú)依賴只需要有 Java 運(yùn)行時(shí)或直接使用官方編好的二進(jìn)制非常適合線上排查。另外在自動(dòng)化測(cè)試和持續(xù)集成場(chǎng)景里MQTT CLI 幾乎是不可替代的。它可以把發(fā)布、訂閱、等消息、斷言結(jié)果全部寫(xiě)進(jìn) shell 腳本里一條命令跑完一套流程。比如我要驗(yàn)證“Broker 重啟后設(shè)備是否能自動(dòng)恢復(fù)連接并重新上報(bào)”以前我只能手動(dòng)重啟、手動(dòng)觀察現(xiàn)在我可以寫(xiě)一段腳本啟動(dòng) MQTT CLI 訂閱設(shè)備主題然后重啟 Broker等待 60 秒再用命令查詢事件是否發(fā)生。整個(gè)過(guò)程不再需要人工盯屏幕結(jié)果直接輸出為腳本返回值。4.2 常用命令與參數(shù)示例MQTT CLI 的命令風(fēng)格非常清晰核心子命令有pub、sub、con、dis等支持連接時(shí)指定 host、port、protocol、username、password 等參數(shù)。我常用的幾個(gè)命令給你列出來(lái)。先看連接并訂閱一個(gè)主題mqttcli sub -h broker.emqx.io -p 1883 -t sen/device01/data -q 1 -C 1這里的-C 1表示只接收一條消息后自動(dòng)退出配合超時(shí)參數(shù)做穩(wěn)定性測(cè)試很好用。如果要持續(xù)訂閱去掉-C即可。再看發(fā)布一條消息mqttcli pub -h 127.0.0.1 -p 1883 -t factory/line01/machine01/status -m {state:running,temp:32.5} -q 1 -r-r表示 Retain 消息-q 1表示 QoS 1。如果你要發(fā)布二進(jìn)制數(shù)據(jù)可以用-m指向文件路徑或者配合 stdin 輸入。實(shí)際工作中我還經(jīng)常這樣組合使用把發(fā)布命令寫(xiě)進(jìn)循環(huán)模擬大量設(shè)備周期性上報(bào)測(cè)試 Broker 在高并發(fā)下的穩(wěn)定性for i in $(seq 1 100); do mqttcli pub -h 127.0.0.1 -p 1883 -t dev/$i/data -m {\id\:\$i\,\ts\:$(date %s)} -q 1 done這條命令一秒之內(nèi)發(fā)布了 100 條不同主題的消息。如果想模擬更真實(shí)的負(fù)載還可以在循環(huán)里加sleep模擬真實(shí)設(shè)備的發(fā)送間隔。除了 HiveMQ MQTT CLIMosquitto 自帶的mosquitto_pub和mosquitto_sub也值得一提它們的實(shí)現(xiàn)更“老派”但穩(wěn)定可靠很多服務(wù)器里已經(jīng)預(yù)裝不需要額外下載。兩者的區(qū)別是MQTT CLI 支持更豐富的輸出格式和參數(shù)更適合高級(jí)調(diào)試mosquitto_pub/sub則輕量到極致適合在資源受限的嵌入式設(shè)備里快速驗(yàn)證。我的建議是本地開(kāi)發(fā)優(yōu)先用 MQTT CLI生產(chǎn)環(huán)境排查哪個(gè)命令現(xiàn)成用哪個(gè)不用死磕工具。注意在 shell 腳本里使用密碼參數(shù)時(shí)盡量通過(guò)環(huán)境變量或配置文件傳入避免密碼出現(xiàn)在 shell 歷史記錄或進(jìn)程列表里。MQTT CLI 支持從配置文件讀取連接信息正式環(huán)境建議用這種方式。5. 三款工具的聯(lián)合實(shí)測(cè)從單條消息到全量報(bào)文5.1 連接統(tǒng)一的測(cè)試 Broker前面我分別講了三款工具的特點(diǎn)但實(shí)際調(diào)試時(shí)它們往往是配合使用的。為了讓你有更直觀的感受我設(shè)計(jì)了一個(gè)完整的聯(lián)調(diào)小場(chǎng)景。假設(shè)我們已經(jīng)在本地啟動(dòng)了一個(gè) MQTT Broker。如果你還沒(méi)有 Broker用 Docker 一條命令就能拉起來(lái)一個(gè)官方 Mosquittodocker run -it --name mqtt-test -p 1883:1883 eclipse-mosquitto:2.0這條命令會(huì)在本機(jī)映射1883端口Broker 啟動(dòng)后沒(méi)有任何鑒權(quán)規(guī)則默認(rèn)本機(jī)可訪問(wèn)適合本地調(diào)試。生產(chǎn)環(huán)境一定要配置用戶名密碼和 ACL這里只是為了演示?,F(xiàn)在假設(shè)場(chǎng)景是有一臺(tái)溫濕度傳感器節(jié)點(diǎn)它每隔 5 秒向主題sensor/node01/data發(fā)布一條 JSON 消息內(nèi)容包含溫度和濕度。同時(shí)還周期性地向sensor/node01/status發(fā)布在線狀態(tài)。我們要驗(yàn)證三件事第一傳感器是否在周期上報(bào)第二上報(bào)的數(shù)據(jù)格式是否完整第三平臺(tái)端訂閱后能不能正確收到這些消息。三款工具在這個(gè)驗(yàn)證過(guò)程中的分工是MQTTX 負(fù)責(zé)“單點(diǎn)查看”MQTT Explorer 負(fù)責(zé)“全局觀察”MQTT CLI 負(fù)責(zé)“模擬自動(dòng)上報(bào)和最終驗(yàn)收”。5.2 用三款工具完成同一個(gè)調(diào)試任務(wù)先用 MQTTX 連上本地 Broker訂閱sensor/#。這個(gè)通配符的寫(xiě)法有點(diǎn)講究#放在末尾表示匹配sensor/下所有層級(jí)所以sensor/node01/data和sensor/node01/status都能收到。然后我手動(dòng)向sensor/node01/data發(fā)布一條測(cè)試消息看消息是否能出現(xiàn)在訂閱列表中。這一步的主要目的是確認(rèn) Broker 鏈路通不通、鑒權(quán)對(duì)不對(duì)、Payload 是否能正常顯示。如果 MQTTX 這里能正常收發(fā)說(shuō)明連接層基本沒(méi)問(wèn)題。接著打開(kāi) MQTT Explorer也連接同一個(gè) Broker。它會(huì)自動(dòng)把當(dāng)前所有主題展開(kāi)成樹(shù)狀。我盯著sensor這個(gè)根節(jié)點(diǎn)觀察它的子節(jié)點(diǎn)是否持續(xù)刷新。如果data節(jié)點(diǎn)的值每隔幾秒更新一次那說(shuō)明傳感器確實(shí)在正常上報(bào)如果status節(jié)點(diǎn)很久都沒(méi)變化那我就要懷疑設(shè)備是不是只上報(bào)了數(shù)據(jù)而沒(méi)有更新?tīng)顟B(tài)。這一步驗(yàn)證的是“設(shè)備實(shí)際在做什么”而不是“你以為它在做什么”。主題樹(shù)不會(huì)撒謊設(shè)備上報(bào)什么它就展示什么。最后用 MQTT CLI 做一次自動(dòng)化驗(yàn)收。我先用下面的命令訂閱sensor/#持續(xù) 5 秒統(tǒng)計(jì)收到的消息數(shù)timeout 5 mqttcli sub -h 127.0.0.1 -p 1883 -t sensor/# -q 1 -x 5s參數(shù)-x 5s表示 Bounded subscription即訂閱最多維持 5 秒自動(dòng)退出。命令執(zhí)行結(jié)束后統(tǒng)計(jì)出來(lái)的消息數(shù)量如果接近“設(shè)備 5 秒上報(bào)一條數(shù)據(jù)”的預(yù)期那說(shuō)明端到端通信穩(wěn)定。接下來(lái)我再模擬一個(gè)新的傳感器節(jié)點(diǎn)sensor/node02持續(xù)向 Broker 發(fā)布模擬數(shù)據(jù)for i in $(seq 1 10); do mqttcli pub -h 127.0.0.1 -p 1883 -t sensor/node02/data \ -m {\temp\:$((20 i)),\hum\:$((50 i))} -q 1 sleep 1 done跑完這條命令后回到 MQTTX 或 MQTT Explorer就能看到sensor/node02/data這個(gè)主題下陸續(xù)出現(xiàn)了 10 條遞增的數(shù)據(jù)。這一整套流程走下來(lái)相當(dāng)于把“人工查看、全局觀察、自動(dòng)化驗(yàn)證”三個(gè)層次全部覆蓋了。如果你平時(shí)開(kāi)發(fā)中遇到“設(shè)備數(shù)據(jù)有時(shí)有有時(shí)沒(méi)有”這種問(wèn)題我強(qiáng)烈推薦用類似的方式從這三個(gè)角度分別排查一遍。6. 常見(jiàn)問(wèn)題與避坑實(shí)錄6.1 連接類問(wèn)題MQTT 調(diào)試中遇到最多的就是連接失敗。第一個(gè)坑是端口寫(xiě)錯(cuò)。明文端口通常是1883TLS 加密端口通常是8883WebSocket 端口可能是8083或8084不同 Broker 配置還不一樣。我見(jiàn)過(guò)很多人拿著1883去連 SSL 端口或者反過(guò)來(lái)結(jié)果自然是連接超時(shí)。第二個(gè)坑是 Client ID 沖突。同一個(gè) Client ID 同時(shí)被多個(gè)連接使用時(shí)新的連接會(huì)把舊的踢下線。排查方法很簡(jiǎn)單先用 MQTTX 建一個(gè)連接再故意用 MQTT CLI 用同樣的 Client ID 去連Broker 端日志就會(huì)提示 session takeover。第三個(gè)坑是防火墻和安全組沒(méi)放行端口這個(gè)在本地開(kāi)發(fā)時(shí)最容易忽略。你本機(jī)連127.0.0.1:1883沒(méi)問(wèn)題但換到局域網(wǎng) IP 就連不上八成就是防火墻攔住了。還有一個(gè)容易被忽略的問(wèn)題公共 Broker 的可用性。broker.emqx.io或者test.mosquitto.org這類公共服務(wù)雖然方便但經(jīng)常有其他開(kāi)發(fā)者也在上面測(cè)試你可能會(huì)收到別人發(fā)布的消息也可能因?yàn)榫W(wǎng)絡(luò)問(wèn)題連不上。所以公共 Broker 只適合“試試工具是否正?!辈贿m合做正式聯(lián)調(diào)。我建議所有嚴(yán)肅一點(diǎn)的開(kāi)發(fā)任務(wù)都使用本地 Broker成本很低又不會(huì)受外部干擾。6.2 消息消費(fèi)與訂閱問(wèn)題訂閱了主題但收不到消息這可能是新手碰到最多的怪問(wèn)題。我總結(jié)了幾個(gè)最常見(jiàn)的元兇。第一個(gè)是主題寫(xiě)錯(cuò)包括大小寫(xiě)、斜杠、多級(jí)通配符放錯(cuò)位置等。MQTT 主題是嚴(yán)格區(qū)分大小寫(xiě)的Sensor/Node01和sensor/node01是兩個(gè)完全不同的主題。第二個(gè)是通配符使用錯(cuò)誤。sport/tennis/player1/#能匹配sport/tennis/player1及其所有子主題但sport/tennis/player1/#/score這種寫(xiě)法是無(wú)效的#必須位于主題末尾。第三個(gè)是 Retain 消息帶來(lái)的誤導(dǎo)。Broker 會(huì)保留最后一條 Retain 消息新訂閱者一進(jìn)來(lái)就收到如果你沒(méi)意識(shí)到這點(diǎn)可能會(huì)誤以為設(shè)備又在發(fā)消息。建議調(diào)試時(shí)把 Retain 關(guān)掉除非你刻意在驗(yàn)證這個(gè)特性。QoS 也是一個(gè)容易踩坑的點(diǎn)。發(fā)布端和訂閱端 QoS 的最終生效規(guī)則是取兩者間的較低值。比如發(fā)布端 QoS 1、訂閱端 QoS 0那這條消息實(shí)際是按 QoS 0 投遞的網(wǎng)絡(luò)抖動(dòng)就可能丟消息。調(diào)試端只用 QoS 0 看起來(lái)沒(méi)問(wèn)題但生產(chǎn)環(huán)境對(duì)可靠性有要求時(shí)就要顯式把 QoS 設(shè)為 1 或 2。另外cleanSession參數(shù)也很重要。如果訂閱端cleanSession為 falseBroker 會(huì)在會(huì)話恢復(fù)時(shí)補(bǔ)發(fā)離線期間的消息如果為 true離線消息會(huì)直接丟棄。很多人在應(yīng)用端反復(fù)重連卻收不到離線消息就是因?yàn)?Broker 把會(huì)話清掉了。6.3 工具使用中的主觀感受與局限性這三款工具雖然整體體驗(yàn)都很好但也各有各的脾氣。MQTTX 在消息吞吐量特別大時(shí)會(huì)顯得有點(diǎn)卡畢竟它要把每條消息都渲染到界面上如果你想看高頻率的原始報(bào)文建議用 MQTT CLI 直接輸出到終端更流暢。MQTT Explorer 的主題樹(shù)在 Broker 上主題特別多時(shí)渲染效率會(huì)下降而且它的發(fā)消息功能相對(duì)簡(jiǎn)陋不適合做復(fù)雜消息的編輯和重發(fā)。MQTT CLI 的參數(shù)確實(shí)多但有些參數(shù)的組合方式一開(kāi)始比較反直覺(jué)比如-x 5s這種帶單位的時(shí)間寫(xiě)法我第一次用的時(shí)候翻了好一會(huì)兒文檔。我的建議是日常開(kāi)發(fā)中給三款工具做一個(gè)固定的分工看消息、發(fā)消息、回放消息用 MQTTX看主題結(jié)構(gòu)、找數(shù)據(jù)缺失用 MQTT Explorer自動(dòng)化驗(yàn)證、線上排查、寫(xiě)回歸腳本用 MQTT CLI。不要試圖在任何一個(gè)工具里完成所有事情工具選對(duì)了調(diào)試效率能翻倍。另外在團(tuán)隊(duì)協(xié)作時(shí)盡量讓所有成員統(tǒng)一使用同一套調(diào)試工具并約定主題命名和消息格式規(guī)范這樣在排查問(wèn)題時(shí)大家看到的數(shù)據(jù)是一致的溝通成本會(huì)低很多。最后再分享一個(gè)小技巧我平時(shí)會(huì)把 MQTTX 和 MQTT CLI 結(jié)合著用剛開(kāi)始開(kāi)發(fā)和調(diào)試一個(gè)新功能時(shí)先用 MQTTX 人工把消息鏈路摸一遍確認(rèn)問(wèn)題和數(shù)據(jù)格式都清晰之后就會(huì)把重復(fù)的驗(yàn)證動(dòng)作寫(xiě)成 MQTT CLI 腳本放到倉(cāng)庫(kù)里作為回歸測(cè)試的一部分下次改了代碼直接一條命令跑完。這些年下來(lái)光是“設(shè)備上報(bào)-平臺(tái)下發(fā)-設(shè)備回復(fù)確認(rèn)”這一條鏈路的回歸腳本我就攢了幾十個(gè)。根據(jù)我個(gè)人的經(jīng)驗(yàn)調(diào)試工具的進(jìn)化真的會(huì)改變物聯(lián)網(wǎng)開(kāi)發(fā)的節(jié)奏——以前是盯著十六進(jìn)制報(bào)文發(fā)呆現(xiàn)在打開(kāi)客戶端就能看懂每條消息的來(lái)龍去脈。趁手的工具加上清晰的調(diào)試流程這套組合拳帶給你的效率提升遠(yuǎn)比你想象的大。