MQTT QoS等級

QoS等級

  • QoS0,At most once,至多一次;
  • QoS1,At least once,至少一次;
  • QoS2,Exactly once,確保只有一次。
    QoS 是消息的發送方(Sender)和接受方(Receiver)之間達成的一個協議:
  • QoS0 代表,Sender 發送的一條消息,Receiver 最多能收到一次,也就是說 Sender 盡力向 Receiver 發送消息,如果發送失敗,也就算了;
  • QoS1 代表,Sender 發送的一條消息,Receiver 至少能收到一次,也就是說 Sender 向 Receiver 發送消息,如果發送失敗,會繼續重試,直到 Receiver 收到消息爲止,但是因爲重傳的原因,Receiver 有可能會收到重複的消息;
  • QoS2 代表,Sender 發送的一條消息,Receiver 確保能收到而且只收到一次,也就是說 Sender 盡力向 Receiver 發送消息,如果發送失敗,會繼續重試,直到 Receiver 收到消息爲止,同時保證 Receiver 不會因爲消息重傳而收到重複的消息。
    注:QoS 是 Sender 和 Receiver 之間達成的協議,不是 Publisher 和 Subscriber 之間達成的協議。也就是說 Publisher 發佈一條 QoS1 的消息,只能保證 Broker 能至少收到一次這個消息;至於對應的 Subscriber 能否至少收到一次這個消息,還要取決於 Subscriber 在 Subscribe 的時候和 Broker 協商的 QoS 等級。

Qos0

在這裏插入圖片描述
Sender 向 Receiver 發送一個包含消息數據的 PUBLISH 包,然後不管結果如何,丟棄掉已發送的 PUBLISH 包,一條消息的發送完成。

QoS1

QoS 要保證消息至少到達 Sender 一次,所以有一個應答的機制。
在這裏插入圖片描述

  1. Sender 向 Receiver 發送一個帶有消息數據的 PUBLISH 包, 並在本地保存這個 PUBLISH 包。
  2. Receiver 收到 PUBLISH 包以後,向 Sender 發送一個 PUBACK 數據包,PUBACK 數據包沒有消息體(Payload),在可變頭中(Variable header)中有一個包標識(Packet Identifier),和它收到的 PUBLISH 包中的 Packet Identifier 一致。
  3. Sender 收到 PUBACK 之後,根據 PUBACK 包中的 Packet Identifier 找到本地保存的 PUBLISH 包,然後丟棄掉,一次消息的發送完成。
  4. 如果 Sender 在一段時間內沒有收到 PUBLISH 包對應的 PUBACK,它將該 PUBLISH 包的 DUP 標識設爲 1(代表是重新發送的 PUBLISH 包),然後重新發送該 PUBLISH 包。重複這個流程,直到收到 PUBACK,然後執行第 3 步。

QoS2

在這裏插入圖片描述

  1. Sender 發送 QoS 爲 2 的 PUBLISH 數據包,數據包 Packet Identifier 爲 P,並在本地保存該 PUBLISH 包;
  2. Receiver 收到 PUBLISH 數據包以後,在本地保存 PUBLISH 包的 Packet Identifier P,並回復 Sender 一個 PUBREC 數據包,PUBREC 數據包可變頭中的 Packet Identifier 爲 P,沒有消息體(Payload);
  3. 當 Sender 收到 PUBREC,它就可以安全地丟棄掉初始的 Packet Identifier 爲 P 的 PUBLISH 數據包,同時保存該 PUBREC 數據包,同時回覆 Receiver 一個 PUBREL 數據包,PUBREL 數據包可變頭中的 Packet Identifier 爲 P,沒有消息體;如果 Sender 在一定時間內沒有收到 PUBREC,它會把 PUBLISH 包的 DUP 標識設爲 1,重新發送該 PUBLISH 數據包(Payload);
  4. 當 Receiver 收到 PUBREL 數據包,它可以丟棄掉保存的 PUBLISH 包的 Packet Identifier P,並回復 Sender 一個 PUBCOMP 數據包,PUBCOMP 數據包可變頭中的 Packet Identifier 爲 P,沒有消息體(Payload);
  5. 當 Sender 收到 PUBCOMP 包,那麼它認爲數據包傳輸已完成,它會丟棄掉對應的 PUBREC 包。如果 Sender 在一定時間內沒有收到 PUBCOMP 包,它會重新發送 PUBREL 數據包。

QoS 和會話(Session)

如果 Client 想接收離線消息,必須使用持久化的會話(Clean Session = 0)連接到 Broker,這樣 Broker 纔會存儲 Client 在離線期間沒有確認接收的 QoS 大於 1 的消息。

QoS降級問題

在 MQTT 協議中,從 Broker 到 Subscriber 這段消息傳遞的實際 QoS 等於:Publisher 發佈消息時指定的 QoS 等級和 Subscriber 在訂閱時與 Broker 協商的 QoS 等級,這兩個 QoS 等級中的最小那一個。

QoS選擇

  1. 在以下情況下你可以選擇 QoS0:
  • Client 和 Broker 之間的網絡連接非常穩定,例如一個通過有線網絡連接到 Broker 的測試用 Client;
  • 可以接受丟失部分消息,比如你有一個傳感器以非常短的間隔發佈狀態數據,所以丟一些也可以接受;
  • 不需要離線消息。
  1. 在以下情況下你應該選擇 QoS1:
  • 你需要接收所有的消息,而且你的應用可以接受並處理重複的消息;
  • 你無法接受 QoS2 帶來的額外開銷,QoS1 發送消息的速度比 QoS2 快很多。
  1. 在以下情況下你應該選擇 QoS2:
  • 你的應用必須接收到所有的消息,而且你的應用在重複的消息下無法正常工作,同時你也能接受 QoS2 帶來的額外開銷。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章