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能够实现端到端的消息处理。

相关文章
相关标签/搜索