MQTT 5.0 协议介绍 - 共享订阅

前言

共享订阅是 MQTT 5.0 协议引入的新特性,至关因而订阅端的负载均衡功能。git

咱们知道通常的非共享订阅的消息发布流程是这样的:github

WechatIMG316.png

在这种结构下,若是订阅节点发生故障,就会致使发布者的消息丢失(QoS 0)或者堆积在 Server 中(QoS 1, 2)。通常状况下,解决这个问题的办法都是直接增长订阅节点,但这样又产生了大量的重复消息,不只浪费性能,在某些业务场景下,订阅节点还须要自行去重,进一步增长了业务的复杂度。服务器

其次,当发布者的生产能力较强时,可能会出现订阅者的消费能力没法及时跟上的状况,此时只能由订阅者自行实现负载均衡来解决,又一次增长了用户的开发成本。网络

协议规范

如今,在 MQTT 5.0 协议中,你能够经过共享订阅特性解决上面提到的问题。当你使用共享订阅时,消息的流向就会变为:负载均衡

WechatIMG317.png

同非共享订阅同样,共享订阅包含一个主题过滤器和订阅选项,惟一的区别在于共享订阅的主题过滤器格式必须是 $share/{ShareName}/{filter} 这种形式。这几个的字段的含义分别是:dom

  • $share 前缀代表这将是一个共享订阅
  • {ShareName} 是一个不包含 "/", "+" 以及 "#" 的字符串。订阅会话经过使用相同的 {ShareName} 表示共享同一个订阅,匹配该订阅的消息每次只会发布给其中一个会话
  • {filter} 即非共享订阅中的主题过滤器

须要注意的是,若是服务端正在向其选中的订阅端发送 QoS 2 消息,而且在分发完成以前网络中断,服务端会在订阅端从新链接时继续完成该消息的分发。若是订阅端的会话在其重连以前终止,服务!端将丢弃该消息而不尝试发送给其余订阅端。若是是 QoS 1 消息,服务端能够等订阅端从新链接以后继续完成分发,也能够在订阅端断开链接时就当即尝试将消息分发给其余订阅端,MQTT 协议没有强制规定,所以须要视服务器的具体实现而定。但若是在等待订阅端重连期间其会话终止,服务端则会将消息尝试发送给其余订阅端。性能

共享策略

虽然共享订阅使得订阅端可以负载均衡地消费消息,但 MQTT 协议并无规定 Server 应当使用什么负载均衡策略。做为参考,EMQ X 提供了 random, round_robin, sticky, hash 四种策略供用户自行选择。spa

  • random: 在全部共享订阅会话中随机选择一个发送消息
  • round_robin: 按照订阅顺序轮流选择
  • sticky: 使用 random 策略随机选择一个订阅会话,持续使用至该会话取消订阅或断开链接再重复这一流程
  • hash: 对发送者的 ClientID 进行 hash 操做,根据 hash 结果选择订阅会话

效果演示

最后,咱们经过一个综合性的示例来演示共享订阅的效果。3d

服务端使用 emqx-v3.2.4,客户端使用 emqtt,emqx 的共享订阅分发策略为默认的 random:code

broker.shared_subscription_strategy = random

使用 ./emqx start 启动 emqx,而后使用 emqtt 启动三个订阅客户端,分别订阅 $share/a/topic, $share/a/topic, $share/b/topic

image-20191111142037391.png

启动一个发布客户端,向 topic 主题发布消息。

image-20191111144814890.png

$share/a/topic$share/b/topic 属于不一样的会话组,非共享订阅主题 topic 会在全部的会话组中进行负载均衡。客户端 sub3 由于组内只有本身一个会话,因此收到了全部消息,而客户端 sub1sub2 则是遵循咱们配置的 random 策略随机接收消息。


更多信息请访问咱们的官网 emqx.io,或关注咱们的开源项目 github.com/emqx/emqx ,详细文档请访问 官方文档

相关文章
相关标签/搜索