emqttd 0.9.0版本的會話(Session)、消息隊列(MQueue)、飛行窗口(Inflight Window)設計

emqttd 0.9.0版本從新設計了MQTT鏈接會話管理

每一個MQTT客戶端鏈接,無論是否持久的(Persistent),都啓動一個鏈接會話進程。緩存

該會話進程管理:服務器

  1. 客戶端的所有訂閱(Subscription)。
  2. 服務器發動到客戶端的,已發送未確認的Qos1/2消息。
  3. 客戶端發送到服務端,未接收到PUBREL的QoS2消息。
  4. 客戶端離線時,持久會話保存離線的Qos1/2消息。
  5. 可選設置,持久會話保存離線的QoS0消息。

MQTT客戶端鏈接能夠從新啓用(Resume)在其餘集羣節點上的會話(Session)。編碼

消息隊列(Message Queue)和飛行窗口(Inflight Window)

每一個MQTT鏈接會話,建立一個簡單的內存消息隊列,和一個正在處理消息的飛行窗口。設計

設計以下:code

|<----------------- Max Len ----------------->|
      -----------------------------------------------
IN -> |       Pending Messages   | Inflight Window  | -> Out
      -----------------------------------------------
                                 |<--- Win Size --->|
  1. 飛行窗口(Inflight Window)保存當前正在發送未確認的Qos1/2消息。窗口值越大,吞吐越高;窗口值越小,消息順序越嚴格。隊列

  2. 當客戶端離線或者飛行窗口(Inflight Window)滿時,消息緩存到隊列。進程

  3. 若是消息隊列滿,先丟棄Qos0消息,或者丟棄最先進入隊列的消息。ip

MQTT QoS1/2消息分配全局惟一的消息ID

每一條QoS1/2消息,分配一個全局惟一的、時間序列的消息ID,用於端到端的消息處理。內存

PktId <-- --> MsgId <-- --> MsgId <-- --> PktId
     |<--- Qos --->|<---PubSub--->|<-- Qos -->|

全局惟一消息ID結構:qt

--------------------------------------------------------
|        Timestamp       |  NodeID + PID  |  Sequence  |
|<------- 64bits ------->|<--- 48bits --->|<- 16bits ->|
--------------------------------------------------------
  1. 64bits時間戳: erlang:system_time if Erlang >= R18, otherwise os:timestamp
  2. Erlang節點ID: 編碼爲2字節
  3. Erlang進程PID: 編碼爲4字節
  4. 進程內部序列號: 2字節的進程內部序列號

總結,emqttd-0.9.0版本的會話、隊列、惟一消息Id設計,配合新版broker擴展Hooks能夠實現端到端的消息處理。

相關文章
相關標籤/搜索