MQTT 協議中的 Keep Alive 。

港澳小肖2501438221發表於2022-05-23

為什麼需要 Keep Alive

MQTT 協議是承載於 TCP 協議之上的,而 TCP 協議以連線為導向,在連線雙方之間,提供穩定、有序的位元組流功能。 但是,在部分情況下,TCP 可能出現半連線問題。所謂半連線,是指某一方的連線已經斷開或者沒有建立,而另外一方的連線卻依然維持著。在這種情況下,半連線的一方可能會持續不斷地向對端傳送資料,而顯然這些資料永遠到達不了對端。為了避免半連線導致的通訊黑洞,MQTT 協議提供了  Keep Alive 機制,使客戶端和  MQTT 伺服器可以判定當前是否存在半連線問題,從而關閉對應連線。

Keep Alive 的機制流程與使用

啟用

客戶端在建立和 MQTT Broker 的連線時,只要將連線請求協議包內的  Keep Alive 可變頭部欄位設定為非 0 值,就可以在通訊雙方間啟用  Keep Alive 機制。  Keep Alive 為 0~65535 的一個整數,代表客戶端傳送兩次 MQTT 協議包之間的最大間隔時間。

而 Broker 在收到客戶端的連線請求後,會檢查可變頭部中的  Keep Alive 欄位的值,如果有值,則 Broker 將會啟用  Keep Alive 機制。

在  MQTT 5.0 標準中,引入了  Server Keep Alive 的概念,允許 Broker 根據自身的實現等因素,選擇接受客戶端請求中攜帶的  Keep Alive 值,或者是覆蓋這個值。如果 Broker 選擇覆蓋這個值,則需要將新值設定在連線確認包( CONNACK) 的  Server Keep Alive 欄位中,客戶端如果在連線確認包中讀取到了  Server Keep Alive,則需要使用該值,覆蓋自己之前的  Keep Alive的值。

Keep Alive 機制流程

  1. 客戶端流程

    在連線建立後,客戶端需要確保, 自己任意兩次 MQTT 協議包的傳送間隔不超過  Keep Alive 的值,如果客戶端當前處於空閒狀態,沒有可傳送的包,則可以傳送  PINGREQ 協議包。

    當客戶端傳送  PINGREQ 協議包後,Broker 必須返回一個  PINGRESP 協議包,如果客戶端在一個可靠 的時間內,沒有收到伺服器的  PINGRESP 協議包,則說明當前存在半連線、或者 Broker 已經下線、或者出現了網路故障,這個時候,客戶端應當關閉當前連線。

  2. Broker 流程

    在連線建立後,Broker 如果沒有在  Keep Alive 的 1.5 倍時間內,收到來自客戶端的任何包,則會認為和客戶端之間的連線出現了問題,此時 Broker 便會斷開和客戶端的連線。

    如果 Broker 收到了來自客戶端的  PINGREQ 協議包,需要回復一個  PINGRESP 協議包進行確認。

  3. 客戶端接管機制

    當 Broker 記憶體在半連線時,如果此時對應的客戶端發起了重連、新的連線,則 Broker 會啟動客戶端接管機制:關閉舊的半連線,然後與客戶端建立新的連線。

    這種機制保證了客戶端不會因為 Broker 內的半連線問題,導致無法進行重連。

如何在 EMQX 中使用 Keep Alive

在  EMQX 中,使用者可以透過配置來自定義  Keep Alive 機制的行為,主要配置欄位有:

zone.${zoneName}.server_keepaliveserver_keepalive 型別 預設值   整型 無

如果沒有設定這個值,則 EMQX 會按照客戶端建立連線時的  Keep Alive 的值,來控制  Keep Alive 的行為。

如果設定了這個值,則 Broker 會對該 zone 下面所有的連線,強制啟用  Keep Alive 機制,並且會使用這個值,覆蓋客戶端連線請求中的值。

zone.${zoneName}.keepalive_backoffkeepalive_backoff 型別 預設值   浮點數 0.75

MQTT 協議中要求 Broker 在 1.5 倍  Keep Alive 時間內,如果沒有收到客戶端的任何協議包,則認定客戶端斷開了連線。

而在 EMQX 中,我們引入了退讓係數(keepalive backoff),並將這個係數透過配置暴露出來,方便使用者更靈活的控制 Broker 端的  Keep Alive 行為。

在引入退讓係數後,EMQX 透過下面的公式來計算最大超時時間:

Keepalive * backoff * 2

backoff 預設值為0.75,因此在使用者不修改該配置的情況下,EMQX 的行為完全符合 MQTT 標準。

更多相關內容請參見  EMQX 配置文件

WebSocket 連線時設定 Keep Alive

EMQX 支援客戶端透過 WebSocket 接入,當客戶端使用 WebSocket 發起連線時,只需要在連線引數中設定上 keepalive 的值即可, 具體見 使用 WebSocket 連線 MQTT 伺服器


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70014415/viewspace-2896535/,如需轉載,請註明出處,否則將追究法律責任。

相關文章