MQTT 客戶端出現連線訂閱等問題時如何排查?

EMQX發表於2023-01-16

大家好,這是一期社群專題 FAQ。我們整理了近期社群中關注度較高的問題,在這裡進行統一彙總解答。

今後本系列內容將不定期推送,敬請關注。

同時,如果大家在使用 EMQX 的過程中遇到問題,歡迎透過以下方式進行解決:

  • 查閱 EMQX 產品檔案部落格文章。
  • 如果在現有資料中未能查詢到問題的解決辦法,可以在問答社群中留言提問,我們會盡快解答您的問題。

Q:向 MQTT Broker 釋出多條訊息,MQTT Broker 向訂閱者轉發這些訊息的時候能否保證原始順序?

MQTT Broker 一定會保證來自同一客戶端的相同主題的訊息按照到達順序被轉發,這與訊息的 QoS 等級無關,QoS 等級不會影響轉發順序,不管是訊息丟失,還是訊息重複,也都不會導致訊息失序。

對於不同主題的訊息,MQTT Broker 不會提供轉發順序保證,我們可以將他們視為進入了不同的通道,比如主題 A 的訊息先於主題 B 的訊息到達 MQTT Broker,但最終可能主題 B 的訊息會更早下發。

Q:我的客戶端無法連線到 EMQX/訂閱失敗/釋出訊息但是對端沒有收到任何訊息,出現這些情況怎麼辦?

A:其實 EMQX 的 Debug 日誌基本已經記錄了所有的行為和現象,透過閱讀 Debug 日誌我們能夠知道客戶端何時發起了連線,連線時指定了哪些欄位,連線是否透過,被拒絕連線的原因是什麼等等。但是由於 Debug 日誌記錄的資訊過多,會帶來額外的資源消耗,並且不利於我們針對單個客戶端或主題進行分析。

所以 EMQX 提供了日誌追蹤功能,我們可以指定想要追蹤的客戶端或主題,EMQX 會將所有與該客戶端或主題相關的 Debug 日誌都輸出到指定日誌檔案中。這樣不管是自己分析除錯,還是尋求社群幫助,都會方便許多。

Q:為什麼會有 Client ID 為 CENSYS 的或者是其他我不認識的客戶端?

A:CENSYS 是一款網際網路探測掃描工具,它會週期性掃描 IPv4 地址空間,探測 HTTP、SSH、MQTT 等協議的預設埠。所以如果你發現有 Client ID 為 CENSYS 的或者其他未知的客戶端接入了你的 MQTT Broker,這意味你目前處於相對較低的安全性保障下。以下措施可以有效幫助你避免這個問題:

  1. 不要使用預設配置,例如 EMQX 用於驗證 HTTP API 訪問許可權的 AppID 與 AppSecret 等
  2. 啟用認證,可以是使用者名稱密碼認證,也可以是 JWT 認證,避免只需要知道 IP 地址就可以登入的尷尬情況
  3. 啟用 TLS 雙向認證,只有持有有效證書的客戶端才能接入系統
  4. 啟用授權,避免非法裝置登入後可以獲取敏感資料
  5. 配置你的防火牆,儘量關閉一些不需要的埠

Q:EMQX 是一個主題一個訊息佇列嗎?

A:不是。EMQX 中的每個客戶端程式都會有一個訊息佇列,這個訊息佇列會儲存所有因飛行視窗滿或連線斷開而暫時無法下發給客戶端的訊息。訊息佇列有最大長度限制,以避免訊息無限制堆積,達到最大長度後,為了使新訊息繼續入隊,EMQX 會陸續丟棄佇列中最老的訊息。訊息佇列最大長度由 max_mqueue_len 這個配置項指定。

Q:EMQX 日誌中出現 "Parse failed for function_clause" 是什麼原因?

A:這個日誌表示報文解析失敗,可能因為這不是一個 MQTT 報文,我們遇到過很多向 MQTT 埠傳送 HTTP 請求的情況,也可能因為報文中包含了非 UTF-8 字元等等。我們可以在這條 "Parse failed..." 日誌中檢索 Frame data 關鍵字以檢視完整的報文,幫助我們分析解析失敗的可能原因。

Q:EMQX 日誌中出現 "Context: maximum heap size reached" 是什麼原因?

A:出現這個日誌通常表示相應的客戶端程式已經達到了最大堆疊記憶體佔用限制,之後這個程式就會被 EMQX 強制 Kill。這一機制存在的原因是為了保證 EMQX 的可用性,避免客戶端程式的記憶體佔用無限制增長最終導致 EMQX OOM。客戶端程式的堆疊佔用主要來源於飛行視窗和訊息佇列中未完成確認或未投遞的訊息,而這兩處訊息堆積的主要原因通常是客戶端消費能力不足,無法及時處理響應訊息。

與此相關的配置項是 force_shutdown_policy,它的配置格式為 <Maximum Message Queue Length>|<Maximum Heap Size>,例如 10000|64MB。其中 <Maximum Heap Size> 就是限制每個客戶端程式能夠佔用的最大堆疊記憶體。

我們見過一些使用者為了不想客戶端程式被強制關閉,不去提升客戶端的消費能力,而是一味增大 <Maximum Heap Size>,這除了給 EMQX 帶來 OOM 風險,也會使得訊息的時延增加,往往得不償失。

版權宣告: 本文為 EMQ 原創,轉載請註明出處。

原文連結:https://www.emqx.com/zh/blog/mqtt-client-faq

相關文章