目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
本文主要介紹 MQTT 協議中 QoS(服務質量) 的詳細內容。
1、概述
MQTT 協議 中規定了消息服務質量(Quality of Service),它保證了在不同的網路環境下消息傳遞的可靠性,QoS 的設計是 MQTT 協議里的重點。作為專為物聯網場景設計的協議,MQTT 的運行場景不僅僅是 PC,而是更廣泛的窄帶寬網路和低功耗設備,如果能在協議層解決傳輸質量的問題,將為物聯網應用的開發提供極大便利。
2、MQTT QoS 等級
MQTT 設計了 3 個 QoS 等級。
- QoS 0:消息最多傳遞一次,如果當時客戶端不可用,則會丟失該消息。
- QoS 1:消息傳遞至少 1 次。
- QoS 2:消息僅傳送一次。
QoS 0 是一種 "fire and forget" 的消息發送模式:Sender (可能是 Publisher 或者 Broker) 發送一條消息之後,就不再關心它有沒有發送到對方,也不設置任何重發機制。
QoS 1 包含了簡單的重發機制,Sender 發送消息之後等待接收者的 ACK,如果沒收到 ACK 則重新發送消息。這種模式能保證消息至少能到達一次,但無法保證消息重覆。
QoS 2 設計了重發和重覆消息發現機制,保證消息到達對方並且嚴格只到達一次。
3、QoS 工作原理
QoS 0 - 最多分發一次
當 QoS 為 0 時,消息的分發依賴於底層網路的能力。發佈者只會發佈一次消息,接收者不會應答消息,發佈者也不會儲存和重發消息。消息在這個等級下具有最高的傳輸效率,但可能送達一次也可能根本沒送達。
Qos 1 - 至少分發一次
當 QoS 為 1 時,可以保證消息至少送達一次。MQTT 通過簡單的 ACK 機制來保證 QoS 1。發佈者會發佈消息,並等待接收者的 PUBACK 報文的應答,如果在規定的時間內沒有收到 PUBACK 的應答,發佈者會將消息的 DUP 置為 1 並重發消息。接收者接收到 QoS 為 1 的消息時應該回應 PUBACK 報文,接收者可能會多次接受同一個消息,無論 DUP 標誌如何,接收者都會將收到的消息當作一個新的消息併發送 PUBACK 報文應答。
QoS 2 - 只分發一次
當 QoS 為 2 時,發佈者和訂閱者通過兩次會話來保證消息只被傳遞一次,這是最高等級的服務質量,消息丟失和重覆都是不可接受的。使用這個服務質量等級會有額外的開銷。
發佈者發佈 QoS 為 2 的消息之後,會將發佈的消息儲存起來並等待接收者回覆 PUBREC 的消息,發送者收到 PUBREC 消息後,它就可以安全丟棄掉之前的發佈消息,因為它已經知道接收者成功收到了消息。發佈者會保存 PUBREC 消息並應答一個 PUBREL,等待接收者回覆 PUBCOMP 消息,當發送者收到 PUBCOMP 消息之後會清空之前所保存的狀態。
當接收者接收到一條 QoS 為 2 的 PUBLISH 消息時,他會處理此消息並返回一條 PUBREC 進行應答。當接收者收到 PUBREL 消息之後,它會丟棄掉所有已保存的狀態,並回覆 PUBCOMP。
無論在傳輸過程中何時出現丟包,發送端都負責重發上一條消息。不管發送端是 Publisher 還是 Broker,都是如此。因此,接收端也需要對每一條命令消息都進行應答。
4、QoS 在發佈與訂閱中的區別
MQTT 發佈與訂閱操作中的 QoS 代表了不同的含義,發佈時的 QoS 表示消息發送到服務端時使用的 QoS,訂閱時的 QoS 表示服務端向自己轉發消息時可以使用的最大 QoS。
- 當客戶端 A 的發佈 QoS 大於客戶端 B 的訂閱 QoS 時,服務端向客戶端 B 轉發消息時使用的 QoS 為客戶端 B 的訂閱 QoS。
- 當客戶端 A 的發佈 QoS 小於客戶端 B 的訂閱 QoS 時,服務端向客戶端 B 轉發消息時使用的 QoS 為客戶端 A 的發佈 QoS。
不同情況下客戶端收到的消息 QoS 可參考下表:
發佈消息的 QoS | 主題訂閱的 QoS | 接收消息的 QoS |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
0 | 2 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
1 | 2 | 1 |
2 | 0 | 0 |
2 | 1 | 1 |
2 | 2 | 2 |
5、如何選擇 MQTT QoS 等級
QoS 級別越高,流程越複雜,系統資源消耗越大。應用程式可以根據自己的網路場景和業務需求,選擇合適的 QoS 級別。
以下情況下可以選擇 QoS 0
- 可以接受消息偶爾丟失。
- 在同一個子網內部的服務間的消息交互,或其他客戶端與服務端網路非常穩定的場景。
以下情況下可以選擇 QoS 1
- 對系統資源消耗較為關註,希望性能最優化。
- 消息不能丟失,但能接受並處理重覆的消息。
以下情況下可以選擇 QoS 2
- 不能忍受消息丟失(消息的丟失會造成生命或財產的損失),且不希望收到重覆的消息。
- 數據完整性與及時性要求較高的銀行、消防、航空等行業。
參考:https://www.emqx.com/zh/blog/introduction-to-mqtt-qos