在這篇文章中摆尝,解釋了 MQTT 中不同的服務(wù)質(zhì)量級(jí)別温艇。“服務(wù)質(zhì)量”這個(gè)詞在之前的文章中出現(xiàn)過(guò)幾次堕汞,讓我們來(lái)看看這個(gè)詞到底是什么意思勺爱。
正文
什么是服務(wù)質(zhì)量?
- 服務(wù)質(zhì)量水平(QoS)是一個(gè)消息的發(fā)送者和限定遞送保證用于特定消息的消息的接收器之間的協(xié)議讯检。MQTT 中有 3 個(gè) QoS 級(jí)別:
1.最多一次(0)
2.至少一次(1)
3.恰好一次(2)琐鲁。
在 MQTT 中談 QoS 時(shí),需要考慮消息傳遞的兩個(gè)方面:
1.消息從發(fā)布客戶(hù)端傳遞到代理人灼。
2.從代理到訂閱客戶(hù)端的消息傳遞围段。
我們將分別查看消息傳遞的兩個(gè)方面,因?yàn)閮烧咧g存在細(xì)微差別投放。向代理發(fā)布消息的客戶(hù)端在向代理發(fā)送消息時(shí)定義了消息的 QoS 級(jí)別奈泪。代理使用每個(gè)訂閱客戶(hù)端在訂閱過(guò)程中定義的 QoS 級(jí)別將此消息傳輸?shù)接嗛喛蛻?hù)端。如果訂閱客戶(hù)端定義的 QoS 低于發(fā)布客戶(hù)端灸芳,則代理會(huì)以較低的服務(wù)質(zhì)量傳輸消息涝桅。
為什么服務(wù)質(zhì)量很重要?
- QoS 是 MQTT 協(xié)議的一個(gè)關(guān)鍵特性烙样。QoS 使客戶(hù)端能夠選擇與其網(wǎng)絡(luò)可靠性和應(yīng)用程序邏輯相匹配的服務(wù)級(jí)別冯遂。因?yàn)?MQTT 管理消息的重新傳輸并保證交付(即使底層傳輸不可靠),QoS 使不可靠網(wǎng)絡(luò)中的通信變得更加容易谒获。
它是如何工作的蛤肌?
- 讓我們仔細(xì)看看每個(gè) QoS 級(jí)別在 MQTT 協(xié)議中是如何實(shí)現(xiàn)的壁却,以及它是如何運(yùn)作的:
-
QoS 0 - 最多一次 (服務(wù)質(zhì)量級(jí)別 0:最多交付一次)
最低 QoS 級(jí)別為零。此服務(wù)級(jí)別可確保盡最大努力交付裸准。不保證交貨展东。接收方不會(huì)確認(rèn)收到消息,并且消息不會(huì)被發(fā)送方存儲(chǔ)和重新傳輸炒俱。QoS 級(jí)別 0 通常被稱(chēng)為“即發(fā)即忘”琅锻,并提供與底層 TCP 協(xié)議相同的保證。
-
QoS 1 - 至少一次 (服務(wù)質(zhì)量級(jí)別 1:至少交付一次)
QoS 級(jí)別 1 保證消息至少傳遞一次給接收者向胡。發(fā)送方存儲(chǔ)消息,直到它從接收方收到確認(rèn)收到消息的 PUBACK數(shù)據(jù)包惊完。一條消息可以多次發(fā)送或傳遞僵芹。
發(fā)送方使用每個(gè)數(shù)據(jù)包中的數(shù)據(jù)包標(biāo)識(shí)符將 PUBLISH 數(shù)據(jù)包與相應(yīng)的 PUBACK 數(shù)據(jù)包進(jìn)行匹配。如果發(fā)送方在合理的時(shí)間內(nèi)沒(méi)有收到 PUBACK 數(shù)據(jù)包小槐,則發(fā)送方重新發(fā)送 PUBLISH 數(shù)據(jù)包拇派。當(dāng)接收者收到 QoS 1 的消息時(shí),它可以立即處理它凿跳。例如件豌,如果接收方是代理,則代理將消息發(fā)送給所有訂閱客戶(hù)端控嗜,然后回復(fù)一個(gè) PUBACK 數(shù)據(jù)包茧彤。
如果發(fā)布客戶(hù)端再次發(fā)送消息,它會(huì)設(shè)置重復(fù) (DUP) 標(biāo)志疆栏。在 QoS 1 中曾掂,此 DUP 標(biāo)志僅用于內(nèi)部目的,不由代理或客戶(hù)端處理壁顶。無(wú)論 DUP 標(biāo)志如何珠洗,消息的接收者都會(huì)發(fā)送 PUBACK。
-
QoS 2 - 恰好一次 (服務(wù)質(zhì)量級(jí)別 2:僅交付一次)
QoS 2 是 MQTT 中最高級(jí)別的服務(wù)若专。此級(jí)別保證每條消息僅被預(yù)期收件人接收一次许蓖。QoS 2 是最安全、最慢的服務(wù)質(zhì)量級(jí)別调衰。該保證由發(fā)送方和接收方之間的至少兩個(gè)請(qǐng)求/響應(yīng)流(四部分握手)提供膊爪。發(fā)送方和接收方使用原始 PUBLISH 消息的數(shù)據(jù)包標(biāo)識(shí)符來(lái)協(xié)調(diào)消息的傳遞。
當(dāng)接收方從發(fā)送方獲得 QoS 2 PUBLISH 數(shù)據(jù)包時(shí)窖式,它會(huì)相應(yīng)地處理發(fā)布消息并使用PUBREC數(shù)據(jù)包回復(fù)發(fā)送方以確認(rèn) PUBLISH 數(shù)據(jù)包蚁飒。如果發(fā)送方?jīng)]有從接收方得到 PUBREC 數(shù)據(jù)包,它會(huì)再次發(fā)送帶有重復(fù) (DUP) 標(biāo)志的 PUBLISH 數(shù)據(jù)包萝喘,直到它收到確認(rèn)為止淮逻。
一旦發(fā)送方收到來(lái)自接收方的 PUBREC 數(shù)據(jù)包琼懊,發(fā)送方就可以安全地丟棄初始的 PUBLISH 數(shù)據(jù)包。發(fā)送方存儲(chǔ)來(lái)自接收方的 PUBREC 數(shù)據(jù)包爬早,并以PUBREL數(shù)據(jù)包進(jìn)行響應(yīng) 哼丈。
接收方得到PUBREL報(bào)文后,可以丟棄所有存儲(chǔ)的狀態(tài)筛严,用PUBCOMP報(bào)文應(yīng)答(發(fā)送方收到PUBCOMP報(bào)文也是如此)醉旦。在接收方完成處理并將 PUBCOMP 數(shù)據(jù)包發(fā)送回發(fā)送方之前,接收方存儲(chǔ)對(duì)原始 PUBLISH 數(shù)據(jù)包的數(shù)據(jù)包標(biāo)識(shí)符的引用桨啃。此步驟對(duì)于避免再次處理消息很重要车胡。發(fā)送方收到 PUBCOMP 數(shù)據(jù)包后,已發(fā)布消息的數(shù)據(jù)包標(biāo)識(shí)符可供重復(fù)使用照瘾。
當(dāng) QoS 2 流完成時(shí)匈棘,雙方都確定消息已傳遞,并且發(fā)送方已確認(rèn)傳遞析命。
如果數(shù)據(jù)包在途中丟失主卫,則發(fā)送方有責(zé)任在合理的時(shí)間內(nèi)重新傳輸消息。如果發(fā)送方是 MQTT 客戶(hù)端或MQTT 代理則同樣如此鹃愤。接收方有責(zé)任相應(yīng)地響應(yīng)每個(gè)命令消息簇搅。
關(guān)于QoS
QoS 的某些方面乍一看并不是很明顯。當(dāng)您使用 QoS 時(shí)软吐,請(qǐng)記住以下幾點(diǎn):
QoS降級(jí)
正如上文已經(jīng)提到瘩将,發(fā)送(發(fā)布)消息的客戶(hù)端和接收消息的客戶(hù)端之間的 QoS 定義和級(jí)別是兩件不同的事情。這兩種交互的 QoS 級(jí)別也可以不同关噪。向代理發(fā)送 PUBLISH 消息的客戶(hù)端定義消息的 QoS鸟蟹。但是,當(dāng)代理將消息傳遞給接收者(訂閱者)時(shí)使兔,代理使用接收者(訂閱者)在訂閱期間定義的 QoS建钥。例如,客戶(hù)端 A 是消息的發(fā)送者虐沥⌒芫客戶(hù)端 B 是消息的接收者。如果客戶(hù)端 B 以 QoS 1 訂閱代理并且客戶(hù)端 A 以 QoS 2 向代理發(fā)送消息欲险,則代理以 QoS 1 將消息傳遞給客戶(hù)端 B(接收者/訂閱者)镐依。消息可以多次傳遞給客戶(hù)端乙,每個(gè)客戶(hù)端的數(shù)據(jù)包標(biāo)識(shí)符是唯一的
MQTT 用于 QoS 1 和 QoS 2 的數(shù)據(jù)包標(biāo)識(shí)符在交互中的特定客戶(hù)端和代理之間是唯一的天试。此標(biāo)識(shí)符在所有客戶(hù)端之間不是唯一的槐壳。一旦流完成,數(shù)據(jù)包標(biāo)識(shí)符就可以重新使用喜每。這種重用是包標(biāo)識(shí)符不需要超過(guò)65535的原因务唐■ㄈ粒客戶(hù)端可以在不完成交互的情況下發(fā)送超過(guò)這個(gè)數(shù)量的消息是不現(xiàn)實(shí)的。
最佳實(shí)踐
- 我們經(jīng)常被問(wèn)到如何選擇正確的 QoS 級(jí)別的建議枫笛。以下是一些可以幫助您進(jìn)行決策的指南吨灭。適合您的 QoS 在很大程度上取決于您的用例。
當(dāng)……時(shí)使用 QoS 0
- 您在發(fā)送方和接收方之間建立了完全或大部分穩(wěn)定的連接刑巧。QoS 0 的一個(gè)經(jīng)典用例是通過(guò)有線連接將測(cè)試客戶(hù)端或前端應(yīng)用程序連接到 MQTT 代理喧兄。
- 您不介意偶爾丟失幾條消息。如果數(shù)據(jù)不是那么重要或數(shù)據(jù)間隔很短啊楚,則某些消息的丟失是可以接受的
- 您不需要消息隊(duì)列吠冤。僅當(dāng)斷開(kāi)連接的客戶(hù)端具有 QoS 1 或 2 和持久會(huì)話時(shí),消息才會(huì)排隊(duì) 恭理。
當(dāng)……時(shí)使用 QoS 1
- 您需要獲取每條消息咨演,并且您的用例可以處理重復(fù)項(xiàng)。QoS 級(jí)別 1 是最常用的服務(wù)級(jí)別蚯斯,因?yàn)?strong>它保證消息至少到達(dá)一次,但允許多次傳遞饵较。當(dāng)然拍嵌,您的應(yīng)用程序必須容忍重復(fù)并能夠相應(yīng)地處理它們。
- 您無(wú)法承受 QoS 2 的開(kāi)銷(xiāo)循诉。QoS 1 傳遞消息的速度比 QoS 2 快得多横辆。
當(dāng)……時(shí)使用 QoS 2
- 一次接收所有消息對(duì)您的應(yīng)用程序至關(guān)重要。如果重復(fù)交付可能損害應(yīng)用程序用戶(hù)或訂閱客戶(hù)端茄猫,則通常會(huì)出現(xiàn)這種情況狈蚤。請(qǐng)注意開(kāi)銷(xiāo)以及 QoS 2 交互需要更多時(shí)間才能完成。
QoS 1 和 2 消息的排隊(duì)
- 使用 QoS 1 和 2 發(fā)送的所有消息都會(huì)排隊(duì)等待離線客戶(hù)端划纽,直到客戶(hù)端再次可用脆侮。但是,這種排隊(duì)只有在客戶(hù)端具有持久會(huì)話時(shí)才有可能 勇劣。