本文主要介紹 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/486248.html
標籤:Java
上一篇:IOS – OpenGL ES 黑白網狀效果 GPUImageCrosshatchFilter
下一篇:Dockerfile是什么呢?
