MQTT 发布/订阅模式

发布订阅模式(Publish-Subscribe Pattern)是一种消息传递模式,它将发送消息的客户端(发布者)与接收消息的客户端(订阅者)解耦,使得两者不需要建立直接的联系也不需要知道对方的存在。

MQTT 发布/订阅模式的精髓在于由一个被称为代理(Broker)的中间角色负责所有消息的路由和分发工作,发布者将带有主题的消息发送给代理,订阅者则向代理订阅主题来接收感兴趣的消息。

在 MQTT 中,主题和订阅无法被提前注册或创建,所以代理也无法预知某一个主题之后是否会有订阅者,以及会有多少订阅者,所以只能将消息转发给当前的订阅者,如果当前不存在任何订阅,那么消息将被直接丢弃。

MQTT 发布/订阅模式有 4 个主要组成部分:发布者、订阅者、代理和主题。

  • 发布者(Publisher)

    负责将消息发布到主题上,发布者一次只能向一个主题发送数据,发布者发布消息时也无需关心订阅者是否在线。

  • 订阅者(Subscriber)

    订阅者通过订阅主题接收消息,且可一次订阅多个主题。MQTT 还支持通过共享订阅的方式在多个订阅者之间实现订阅的负载均衡。

  • 代理(Broker)

    负责接收发布者的消息,并将消息转发至符合条件的订阅者。另外,代理也需要负责处理客户端发起的连接、断开连接、订阅、取消订阅等请求。

  • 主题(Topic)

    主题是 MQTT 进行消息路由的基础,它类似 URL 路径,使用斜杠 / 进行分层,比如 sensor/1/temperature。一个主题可以有多个订阅者,代理会将该主题下的消息转发给所有订阅者;一个主题也可以有多个发布者,代理将按照消息到达的顺序转发。

    MQTT 还支持订阅者使用主题通配符一次订阅多个主题。更多关于 MQTT 主题的介绍可查看博客:通过案例理解 MQTT 主题与通配符

MQTT 发布/订阅中的消息路由

在 MQTT 发布/订阅模式中,一个客户端既可以是发布者,也可以是订阅者,也可以同时具备这两个身份。 当客户端发布一条消息时,它会被发送到代理,然后代理将消息路由到该主题的所有订阅者。 当客户端订阅一个主题时,它会收到代理转发到该主题的所有消息。

一般来说,大多数发布/订阅系统主要通过以下两种方式过滤并路由消息。

  • 根据主题

    订阅者向代理订阅自己感兴趣的主题,发布者发布的所有消息中都会包含自己的主题,代理根据消息的主题判断需要将消息转发给哪些订阅者。

  • 根据消息内容

    订阅者定义其感兴趣的消息的条件,只有当消息的属性或内容满足订阅者定义的条件时,消息才会被投递到该订阅者。

MQTT 协议是基于主题进行消息路由的,在这个基础上,EMQX 从 3.1 版本开始通过基于 SQL 的规则引擎提供了额外的按消息内容进行路由的能力。关于规则引擎的详细信息,请查看 EMQX 文档

MQTT 与 HTTP 请求响应

HTTP 是万维网数据通信的基础,其简单易用无客户端依赖,被广泛应用于各个行业。在物联网领域,HTTP 也可以用于连接物联网设备和 Web 服务器,实现设备的远程监控和控制。

虽然使用简单、开发周期端,但是基于请求响应的 HTTP 在物联网领域的应用却有一定的局限性。首先,协议层面 HTTP 报文相较与 MQTT 需要占用更多的网络开销;其次,HTTP 是一种无状态协议,这意味着服务器在处理请求时不会记录客户端的状态,也无法实现从连接异常断开中恢复;最后,请求响应模式需要通过轮询才能获取数据更新,而 MQTT 通过订阅即可获取实时数据更新。

发布订阅模式的松耦合特性,也给 MQTT 带来了一些副作用。由于发布者并不知晓订阅者的状态,因此发布者也无法得知订阅者是否收到了消息,或者是否正确处理了消息。为此,MQTT 5.0 增加了请求响应特性,以实现订阅者收到消息后向某个主题发送应答,发布者收到应答后再进行后续操作。

MQTT 与消息队列

尽管 MQTT 与消息队列的很多行为和特性非常接近,比如都采用发布/订阅模式,但是他们面向的场景却有着显著的不同。消息队列主要用于服务端应用之间的消息存储与转发,这类场景往往数据量大但客户端数量少。MQTT 是一种消息传输协议,主要用于物联网设备之间的消息传递,这类场景的特点是海量的设备接入、管理与消息传输。

在一些实际的应用场景中,MQTT 与消息队列往往会被结合起来使用,以使 MQTT 服务器能专注于处理设备的连接与设备间的消息路由。比如先由 MQTT 服务器接收物联网设备上报的数据,然后再通过消息队列将这些数据转发到不同的业务系统进行处理。

不同于消息队列,MQTT 主题不需要提前创建。MQTT 客户端在订阅或发布时即自动的创建了主题,开发者无需再关心主题的创建,并且也不需要手动删除主题。

结语

MQTT 的发布/订阅机制可以很轻易地满足我们一对一、一对多、多对一的通信需要。这也在很大程度上拓宽了 MQTT 在 IoT 领域之外的应用,像网络直播互动、手机消息推送等行业场景,都非常适合使用 MQTT。

至此,相信读者已对 MQTT 的发布/订阅模式有了深刻的理解,接下来,可查看博客创建 MQTT 连接时如何设置参数?了解如何创建一个 MQTT 连接。或访问 EMQ 提供的 MQTT 入门与进阶系列文章学习 MQTT 主题及通配符、保留消息、遗嘱消息等相关概念,探索 MQTT 的更多高级应用,开启 MQTT 应用及服务开发。

版权声明: 本文为 EMQ 原创,转载请注明出处。

原文链接:https://www.emqx.com/zh/blog/mqtt-5-introduction-to-publish-subscribe-model

MQTT 发布/订阅模式介绍的更多相关文章

  1. Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 如何实现发布--订阅模式? 发布---订阅模式的代码封装 如何取消订阅事件? 全局--发布订阅对象代码封装 理解模块间通信 回到 ...

  2. [转] Javascript中理解发布--订阅模式

    发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 现实生活中的发布- ...

  3. JS中什么是发布--订阅模式?

    转载文章部分内容: 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. ...

  4. 【转】Javascript中理解发布--订阅模式

    Javascript中理解发布--订阅模式 阅读目录 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时 ...

  5. python使用rabbitMQ介绍三(发布订阅模式)

    一.模式介绍 在前面的例子中,消息直接发送到queue中. 现在介绍的模式,消息发送到exchange中,消费者把队列绑定到exchange上. 发布-订阅模式是把消息广播到每个消费者,每个消费者接收 ...

  6. 第三节: List类型的介绍、生产者消费者模式、发布订阅模式

    一. List类型基础 1.介绍 它是一个双向链表,支持左进.左出.右进.右出,所以它即可以充当队列使用,也可以充当栈使用. (1). 队列:先进先出, 可以利用List左进右出,或者右进左出(Lis ...

  7. NetMQ(三): 发布订阅模式 Publisher-Subscriber

    ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...

  8. RabbitMQ/JAVA (发布/订阅模式)

    发布/订阅模式即生产者将消息发送给多个消费者. 下面介绍几个在发布/订阅模式中的关键概念-- 1. Exchanges (转发器) 可能原来我们都是基于一个队列发送和接收消息.现在介绍一下完整的消息传 ...

  9. javascript设计模式——发布订阅模式

    前面的话 发布—订阅模式又叫观察者模式,它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在javascript开发中,一般用事件模型来替代传统的发布—订阅模 ...

  10. NetMQ 发布订阅模式 Publisher-Subscriber

    第一部分引用于:点击打开 1:简单介绍 PUB-SUB模式一般处理的都不是系统的关键数据.发布者不关注订阅者是否收到发布的消息,订阅者也不知道自己是否收到了发布者发出的所有消息.你也不知道订阅者何时开 ...

随机推荐

  1. PHP解密支付宝小程序的加密数据,手机号等。

    1.小程序端代码示例 my.getPhoneNumber({ success: (res) => { let encryptedData = res.response; my.httpReque ...

  2. Mysql数据库基础第五章:(一)事务

    Mysql数据库基础系列 软件下载地址 提取码:7v7u 数据下载地址 提取码:e6p9 mysql数据库基础第一章:(一)数据库基本概念 mysql数据库基础第一章:(二)mysql环境搭建 mys ...

  3. Windows.h 文件学习

    SDk :软件开发工具包 Api  :Windows操作系统提供给应用程序编程的接口,windows.h 窗口:窗口是屏幕上的一块矩形区域,是Windows应用程序与用户进行交互的接口,分为客户区与非 ...

  4. python spacy [E050] Can't find model 'en_core_web_sm'

    出现问题 [E050] Can't find model 'en_core_web_sm' 使用管理员权限打开shell控制台,输入命令 python -m spacy download en_cor ...

  5. Ubuntu更换国内apt-get源

    更换方法: cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i 's/archive.ubuntu.com/mirrors.u ...

  6. windows 10中Microsoft Edge Beta登录账户提示:以管理员身份运行 Microsoft Edge 时不支持登录。请以非管理员身份重新启动 Microsoft Edge,然后重新尝试登录。的解决方案

    windows 10中Microsoft Edge Beta登录账户提示:以管理员身份运行 Microsoft Edge 时不支持登录.请以非管理员身份重新启动 Microsoft Edge,然后重新 ...

  7. 了解ASP (一)

    1. ASP是什么? ASP 指 Active Server Pages (动态服务器页面), 是在 IIS 中运行的程序.ASP 文件的扩展名是 ".asp" 2. ASP与HT ...

  8. 安装centos,ubuntu系统

    安装centos系统 1.首先进入VMware,新建虚拟机,选择典型,然后下一步 2.稍后安装系统,下一步 3.因为此次安装的是centos7.9系统,因此版本选择7 64位,下一步 4.选择虚拟机的 ...

  9. seqsever 查询多个表的条数,并以列的形式展现

    select sum(a) a,sum(b) b,sum(c) c,SUM(d) d,sum(a1) a1,sum(b1) b1,sum(c1) c1,SUM(d1) d1 from( select ...

  10. JS 时间的获取和比较

    JS获取时间 获取当前时间 var date = new Date(); 可指定某种格式来获取时间,或者将字符串转换成时间 var date = new Date("2019-09-24 T ...