1. 程式人生 > >MQTT Mosquitto安裝和使用

MQTT Mosquitto安裝和使用

物聯網(Internet of Things,IoT)最近曝光率越來越高。雖然HTTP是網頁的事實標準,不過機器之間(Machine-to-Machine,M2M)的大規模溝通需要不同的模式:之前的請求/回答(Request/Response)模式不再合適,取而代之的是釋出/訂閱(Publish/Subscribe)模式。這就是輕量級、可擴充套件的MQTT(Message Queuing Telemetry Transport)可以施展拳腳的舞臺。

由於物聯網的環境是非常特別的,所以MQTT遵循以下設計原則:

  1. 精簡,不新增可有可無的功能。
  2. 釋出/訂閱(Pub/Sub)模式,方便訊息在感測器之間傳遞。
  3. 允許使用者動態建立主題,零運維成本。
  4. 把傳輸量降到最低以提高傳輸效率。
  5. 把低頻寬、高延遲、不穩定的網路等因素考慮在內。
  6. 支援連續的會話控制。
  7. 理解客戶端計算能力可能很低。
  8. 提供服務質量管理。
  9. 假設資料不可知,不強求傳輸資料的型別與格式,保持靈活性。

釋出/訂閱模式

與請求/回答這種同步模式不同,釋出/定義模式解耦了釋出訊息的客戶(釋出者)與訂閱訊息的客戶(訂閱者)之間的關係,這意味著釋出者和訂閱者之間並不需要直接建立聯絡。打個比方,你打電話給朋友,一直要等到朋友接電話了才能夠開始交流,是一個典型的同步請求/回答的場景;而給一個好友郵件列表發電子郵件就不一樣,你發好電子郵件該幹嘛幹嘛,好友們到有空了去檢視郵件就是了,是一個典型的非同步釋出/訂閱的場景。
熟悉程式設計的同學一定非常熟悉這種設計模式了,因為它帶來了這些好處:

  1. 釋出者與訂閱者不比了解彼此,只要認識同一個訊息代理即可。
  2. 釋出者和訂閱者不需要互動,釋出者無需等待訂閱者確認而導致鎖定。
  3. 釋出者和訂閱者不需要同時線上,可以自由選擇時間來消費訊息。

主題

MQTT是通過主題對訊息進行分類的,本質上就是一個UTF-8的字串,不過可以通過反斜槓表示多個層級關係。主題並不需要建立,直接使用就是了。
主題還可以通過萬用字元進行過濾。其中,+可以過濾一個層級,而*只能出現在主題最後表示過濾任意級別的層級。舉個例子:

  • building-b/floor-5:代表B樓5層的裝置。
  • +/floor-5:代表任何一個樓的5層的裝置。
  • building-b/*:代表B樓所有的裝置。

注意,MQTT允許使用萬用字元訂閱主題,但是並不允許使用萬用字元廣播。

服務質量

為了滿足不同的場景,MQTT支援三種不同級別的服務質量(Quality of Service,QoS)為不同場景提供訊息可靠性:

  1. 級別0:盡力而為。訊息傳送者會想盡辦法傳送訊息,但是遇到意外並不會重試。
  2. 級別1:至少一次。訊息接收者如果沒有知會或者知會本身丟失,訊息傳送者會再次傳送以保證訊息接收者至少會收到一次,當然可能造成重複訊息。
  3. 級別2:恰好一次。保證這種語義肯待會減少併發或者增加延時,不過丟失或者重複訊息是不可接受的時候,級別2是最合適的。

服務質量是個老話題了。級別2所提供的不重不丟很多情況下是最理想的,不過往返多次的確認一定對併發和延遲帶來影響。級別1提供的至少一次語義在日誌處理這種場景下是完全OK的,所以像Kafka這類的系統利用這一特點減少確認從而大大提高了併發。級別0適合雞肋資料場景,食之無味棄之可惜,就這麼著吧。

訊息型別

MQTT擁有14種不同的訊息型別:

  1. CONNECT:客戶端連線到MQTT代理
  2. CONNACK:連線確認
  3. PUBLISH:新發布訊息
  4. PUBACK:新發布訊息確認,是QoS 1給PUBLISH訊息的回覆
  5. PUBREC:QoS 2訊息流的第一部分,表示訊息釋出已記錄
  6. PUBREL:QoS 2訊息流的第二部分,表示訊息釋出已釋放
  7. PUBCOMP:QoS 2訊息流的第三部分,表示訊息釋出完成
  8. SUBSCRIBE:客戶端訂閱某個主題
  9. SUBACK:對於SUBSCRIBE訊息的確認
  10. UNSUBSCRIBE:客戶端終止訂閱的訊息
  11. UNSUBACK:對於UNSUBSCRIBE訊息的確認
  12. PINGREQ:心跳(空閒時發一個)
  13. PINGRESP:確認心跳
  14. DISCONNECT:客戶端終止連線前優雅地通知MQTT代理

MQTT代理

市面上有相當多的高質量MQTT代理,其中mosquitto是一個開源的輕量級的C實現,完全相容了MQTT 3.1和MQTT 3.1.1。下面我們就以mosquitto為例演示一下MQTT的使用。環境是Ubuntu 14.04.1 LTS,簡單起見MQTT代理和客戶端都安裝在同一臺伺服器上了。
安裝mosquitto以及搭配的客戶端:

sudo apt-get install mosquitto mosquitto-clients 

簡單測試

一個完整的MQTT示例包括一個代理器,一個釋出者和一個訂閱者。測試分為以下幾個步驟:

  1. 啟動服務mosquitto。
  2. 訂閱者通過mosquitto_sub訂閱指定主題的訊息。
  3. 釋出者通過mosquitto_pub釋出指定主題的訊息。
  4. 代理伺服器把該主題的訊息推送到訂閱者。

在本例中,釋出者、代理和訂閱者均為localhsot,但是在實際的情況下三種並不是同一個裝置,在mosquitto中可通過-h(--host)設定主機名稱(hostname)。為了實現這個簡單的測試案例,需要在linux中開啟三個控制檯,分別代表代理伺服器、釋出者和訂閱者。

啟動代理服務

mosquitto -v
【-v】列印更多的除錯資訊

訂閱主題

mosquitto_sub -v -t sensor
【-t】指定主題,此處為sensor
【-v】列印更多的除錯資訊

釋出內容

mosquitto_pub -t sensor -m 12
【-t】指定主題
【-m】指定訊息內容

執行結果

當釋出者推送訊息之後,訂閱者獲得以下內容
sensor 12
而代理伺服器控制檯中會出現——連線、訊息釋出和心跳等除錯資訊。通過代理伺服器的除錯輸出可以對MQTT協議的相關過程有所瞭解。