MQTT-共享订阅
共享订阅
在普通的订阅中,每发布一条消息,所有匹配的订阅端都会收到该消息。当某个订阅端的消费速度无法跟上消息的生产速度时,没有办法将其中一部分消息分流到其他订阅端来消费。这就使得订阅端容易成为整个消息系统的性能瓶颈。
- 解决办法
MQTT 5.0 引入了共享订阅特性,它使得 MQTT 服务端可以在使用特定订阅的客户端之间均衡地分配消息负载。
这表示,当我们有两个客户端共享一个订阅时,那么发布的消息都只投递给其中一个客户端。类似:订阅者集群,负载均衡,提高消费性能
订阅分类
启用共享订阅:为一组订阅者的原始主题添加指定前缀
前缀格式 | 示例 | 前缀 | 真实主题名 |
---|---|---|---|
群组格式 | $share/g/test/a | $share/g | test/a |
非群组格式 | $queue/test/a | $queue/ | test/a |
群组订阅
通过在原始主题前
添加 $share/<group-name>
前缀为分组的订阅者启用共享订阅。组名可以是任意字符串
。EMQX 同时将消息转发给不同的组,属于同一组的订阅者可以使用负载均衡接收消息。
案例说明
订阅者 sub_1
、sub_2
和 sub_3
是组 g1
的成员,订阅者 sub_4
和 sub_5
是组 g2
的成员,而所有订阅者都订阅了原始主题 test/1
。共享订阅的主题是 $share/g1/test/1
和 $share/g2/test/1
。
当 EMQX 发布消息 msg1
到原始主题 test/1
时:
- EMQX 将
msg1
发送给g1
和g2
两个组。 sub_1
、sub_2
、sub_3
中的一个订阅者将接收msg1
。sub_4
和sub_5
中的一个订阅者将接收msg1
。
案例演示
创建订阅者
- sub_1
- 主题
$share/g1/test/1
- 主题
- sub_2
- 主题
$share/g1/test/1
- 主题
- sub_3
- 主题
$share/g1/test/1
- 主题
- sub_4
- 主题
$share/g2/test/1
- 主题
- sub_5
- 主题
$share/g2/test/1
- 主题
发布者发布消息
- publish 发布消息
- 主题
test/1
- 主题
订阅者接收消息
g1
组 中 只有sub_2
接收到
g2
组 中 只有sub_5
接收到
非群组订阅
通过在原始主题前
添加 $queue/
前缀为非群组订阅者启用共享订阅。它是 $share
订阅的一种特例,可以理解为所有订阅者都在一个订阅组。
案例说明
订阅者 sub_queue_1
、sub_queue_2
和 sub_queue_3
都订阅主题 $queue/test/q
。原始主题为 test/q
。 发布消息 msg1
、msg2
、msg3
到原始主题 test/q
时,sub_queue_1
、sub_queue_2
和 sub_queue_3
各自收到一个消息。
案例演示
创建订阅者
- sub_queue_1
- 主题
$queue/test/q
- 主题
- sub_queue_2
- 主题$queue/test/q
- sub_queue_3
- 主题
$queue/test/q
- 主题
发布者发布消息
- publish 发布消息
- 主题
test/q
- 连续发送三个消息
- 三个订阅者各收到一条
- 主题
订阅者接收消息
sub_queue_1
订阅者 sub_queque_1
收到 消息 3
sub_queue_2
订阅者 sub_queque_2
收到 消息 1
sub_queue_3
订阅者 sub_queque_3
收到 消息 2
负载均衡策略
可通过Dashboard进行负载均衡算法的配置【管理>>MQTT配置】
策略简介
- 随机(Random)
在共享订阅组内随机选择一个会话发送消息。
- 轮询(Round Robin)
在共享订阅组内按顺序选择一个会话发送消息,循环往复。
- 哈希(Hash)
基于某个字段的哈希结果来分配。
- 粘性(Sticky)
在共享订阅组内随机选择一个会话发送消息,此后保持这一选择,直到该会话结束再重复这一过程。
- 本地优先(Local)
随机选择,但优先选择与消息的发布者处于同一节点的会话,如果不存在这样的会话,则退化为普通的随机策略。