MQTT发布/订阅模式
发布/订阅(Pub/Sub)架构提供了一种灵活的、可伸缩的方式来构建能够处理许多连接的客户端的分布式系统。
MQTT基于发布/订阅架构,支持持久会话与服务质量QoS功能,实现了发布者与订阅者在空间、时间以及同步等方面的解耦。
发布/订阅模式
发布/订阅模式(Pub/Sub),是软件体系结构的消息传递模式,其特点是支持以解耦的方式在不同组件或系统之间进行通信。
在这种模式中,有两个重要角色,分别是生成消息的发布者与接收消息的订阅者。
与传统C/S请求响应的通信模式相比,Pub/Sub模式,通过在中间增加代理服务器,使发布者和订阅者之间不需要进行端对端的通信,进而将消息的发布者与订阅者完全解耦。这种解耦使得通信过程更快、更高效。
Pub/Sub模式在三个方面实现了解耦,以实现最佳效率:
- 空间解耦: 发布者和订阅者不需要相互了解(例如,不交换IP地址和端口)。
- 时间解耦: 发布服务器和订阅服务器不需要同时运行。
- 同步解耦: 在发布或接收期间,不需要中断操作。
MQTT是遵循发布/订阅模式的消息传递协议之一。
MQTT使用基于代理的模型,其中客户机连接到代理,消息发布到指定主题。然后,订阅者从代理订阅该主题并接收已发布的消息。
因而MQTT协议中也支持Pub/Sub模式中的解耦:
- MQTT只需要知道代理的主机名或I与端口号就可以发布和订阅消息,在空间上解耦了发布者和订阅者。
- MQTT通过支持持久会话和消息缓存,从而允许代理为未联机的客户机存储消息,在时间上解耦了发布者和订阅者。
- MQTT支持单个连接在多线程上同时分别进行订阅和发布,实现了同步解耦。
消息过滤
消息过滤是发布/订阅模式的一个重要功能,因为其控制订阅者能够接收到什么消息。
发布/订阅模式支持三种过滤选项,分别是主题过滤、内容过滤以及类型过滤。
主题过滤
在主题过滤模式中,代理根据主题对消息进行过滤。
主题是层次结构,层次之间用斜杠“/”分隔。
订阅者订阅特定的主题,代理根据主题的层次结构将消息路由到适当的订阅者。
优点
- 简单易用
- 灵活,允许分层的主题结构
- 高效,仅将消息发送给特定的订阅者(订阅该主题)
缺点
- 发布者和订阅者需要事先就主题层次结构达成一致
- 仅限于基于主题层次结构筛选消息
Pub/Sub 中基于主题的过滤用例:
MQTT的主题过滤
MQTT仅支持使用基于主题的消息过滤。
每条消息都包含一个主题,代理将消息发送给订阅该主题的每个订阅者。
内容过滤
在内容过滤模式中,代理根据消息内容对消息进行过滤,过滤方式是通过配置过滤器表达式。
订阅者通过订阅特定的过滤表达式来接收消息,代理根据消息的内容将消息路由到适当的订阅者。
MQTT不支持内容过滤模式。
优点
- 对接收消息提供更细粒度的控制。
- 允许基于消息内容而不仅仅是主题层次结构进行筛选。
- 更灵活,允许复杂的过滤表达式。
缺点
- 比主题过滤复杂,使用难。
- 发布者需要在消息中包含用于过滤的字段。
- 大量过滤时影响性能。
案例
适用于消息没有基于主题区分,订阅者对基于其内容的特定消息子集感兴趣。
例如,在物流应用程序中,订阅者可能只对接收有特定跟踪号码的包的消息感兴趣。订阅者将订阅一个过滤表达式,如“trace-number=‘123456’”,而代理将只向订阅者发送与该表达式匹配的消息。
类型过滤
在类型过滤模式中,代理根据消息的类型或类来进行过滤。
适用于过滤面向对象语言的类作为消息的情况,通过父类、类、子类等层次结构进行过滤。
订阅者订阅指定类型,代理将符合该类型以及子类的消息路由到订阅者。
优点
- 易于使用,特别是在使用面向对象语言时。
- 提供高度的灵活性和可扩展性。
缺点
- 仅限于基于消息类型的筛选。
- 发布者和订阅者需要事先就消息类型层次结构达成一致。
案例
类型过滤适用于消息被组织成类层次结构,订阅者对基于其类的特定类型或消息子集感兴趣。
例如,订阅者对发布者产生的所有异常消息感兴趣,只需要订阅“Exception”类型,代理就可以将所有异常(包括继承该Exception类型的子类型)消息路由管理。
可伸缩性
在传统的C/S模式中,如果有大量的Client连接时,Server会限制连接的Client数量,这种模式会限制可伸缩性。
Pub/Sub模式通过以下几个功能提高可伸缩性:
Pub/Sub模式功能 | 说明 |
---|---|
以事件驱动的方式处理消息 | MQTT代理可以在不牺牲系统性能的情况下处理更多的并发连接。 |
消息缓存 | MQTT代理可以快速检索消息并传递给订阅者,无需额外处理。 |
智能消息路由 | MQTT代理确保消息仅传递给需要的订阅者,减少不必要的网络流量。 |
MQTT遵循Pub/Sub模式,具有这种模式拥有的可伸缩性,使得其非常适合于物联网。
尽管有这些优势,但是扩展到数百万的连接仍然对Pub/Sub模式的MQTT代理构成挑战。在这种情况下,可以使用集群代理节点将负载分布到多个服务器上,而负载均衡器可以确保流量均匀分布。
消息队列的区别
MQTT指的是IBM的MQ系列的产品Telemetry Transport,与“消息队列”没有任何关系。
下面是MQTT与消息队列的几点区别:
- 消息队列会存储每个传入的消息,直到客户端或使用者处理它们。如果没有客户端处理该消息,则该消息将一直保留在消息队列中。在MQTT中没有客户端订阅的主题上的会被丢弃。
- 消息队列中,消息只能由一个使用者处理。在MQTT中,订阅主题的每个订阅者都会获得消息。
- 队列必须命名,必须显式创建。只有在命名并创建队列之后,才能发布或使用消息。MQTT主题非常灵活,可以动态创建。
- 原文作者:生如夏花
- 原文链接:https://blduan.top/post/%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE/mqtt/mqtt%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E6%A8%A1%E5%BC%8F/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。