文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

欢迎来到MQTT基础入门第二部分。这是一系列关于MQTT协议核心特征和概念的博文。在这第二篇文章中,我们将讨论发布/订阅模式。我们首先看看发布/订阅本身的一般特征,然后再着重讨论MQTT。我们还将说明MQTT与传统消息队列协议的差异。

在第一篇文章中,我们介绍了MQTT的来源和历史。 如果你还没有阅读过,你一定要看看。

发布/订阅模式

发布/订阅模式(pub/sub)是传统客户端-服务器模型的一个替代模式。在传统的客户机-服务器模型中,客户端直接与端点进行通信。但是,Pub/Sub模式解耦了发送消息的客户端(发布者)与其它接收消息的客户端(订阅者)。这意味着发布者和订阅者并不知道彼此的存在。有一个发布者和订阅者都知道的第三方,称作代理者,它过滤所有传入的消息并进行相应的分发。因此,让我们深入了解刚才所提及方面的更多细节。但记住,总体而言,这仍是pub/sub一些的基本信息,我们会在随后讨论MQTT的具体细节。

第 1 段(可获 2.75 积分)

MQTT Publish / Subscribe

MQTT发布/订阅

如前所述,发布/订阅的重点是发布者和接收者间的解耦,这可以在多个纬度上进行区分:

  • 空间解耦:发布者和订阅者不需要互相了解(例如通过ip地址和端口)

  • 时间解耦:发布者和订阅者不需要同时运行。

  • 同步解耦:在发布或接收过程中,两个组件的操作都不会停止。

总之,发布/订阅解耦了消息的发布者和接收者,通过消息过滤,可以让客户端接只收特定的消息。 解耦有三个维度:空间、时间、同步。

第 2 段(可获 1.33 积分)

可扩展性

与传统的客户端-服务器相比,发布/订阅也提供了更大的可扩展性。这是因为代理上的操作可以被高度并行化以及事件驱动处理。消息缓存和消息的智能路由对提升可扩展性也是取决定性作用的。但是扩展发布/订阅到数百万级的连接绝对是一个挑战。这可以通过使用集群代理节点,以便将负载均衡到多个服务器上(这超出该文章的范围,我们将在另一篇文章中详细讨论这个)。

第 3 段(可获 1.16 积分)

消息过滤

所以,有趣的是,代理如何过滤消息让订阅者只接收他们感兴趣的消息?

选项1: 基于主题的过滤

这种过滤是基于主题或话题的,主题或话题是消息的一部分。接收端订阅他对代理感兴趣的主题,并从代理处获得他所订阅主题的所有相关消息。主题通常是具有层次结构的字符串,允许基于有限数量的表达式进行过滤。

选项2: 基于内容的过滤
第 4 段(可获 1.18 积分)

基于内容的过滤,因名思意就是代理基于某种内容过滤语言对消息进行过滤。因此,客户端订阅他们感兴趣的消息的过滤查询。一个大的弊端是必须预先知道消息的内容并且消息不能被轻易的加密或更改。

选项3: 基于类型的过滤

使用面向对象语言时,基于消息(事件)的类型/类进行过滤是一种常见的做法. 在这种情况下,订阅者可以监听来自类型异常或其任何子类型的所有消息。

第 5 段(可获 1.25 积分)

当然,发布/订阅不是一颗银弹,要事先考虑好再去使用。发布/订阅的关键是发布者和订阅者间的解耦,这给它带来了一些挑战。你必须事先知道已发布数据的结构。在基于主题的过滤中,发布者和订阅者都必须知道正确的使用主题。另一方面是消息的递送,发布者不能假定有人正在监听他发送的消息。因此消息可能没有被任一订阅者所读到。

第 6 段(可获 1.34 积分)

MQTT

现在我们已经学到了很多关于发布/订阅的知识,这些都是通用的知识,不仅限于 MQTT。MQTT 实现了以上所提及的所有特性,这取决于你想要干什么。MQTT 解耦了发布者和订阅者的关系。它们只需要知道代理的主机地址和端口就可以发布或者订阅消息。同时 MQTT 也解耦了时间,但这只是一个备用的行为,因为绝大多数的用例都是近乎实时的。当然,代理还可以为客户端在不在线时提供消息存储功能(这个要求两个条件:客户端一次连接并保持会话的持久性,然后其订阅了某个主题的消息,而且其 QoS 的值大于 0)。MQTT 同时还解耦了同步功能,因为多数客户端库都是基于回调或者类似技术实现异步操作的。因此它不会堵塞其他的任务对某个消息的等待或者消息发布。但是有一些特定的用例是需要同步。因此某些库提供了同步 API 用于等待某个特定的消息。但是通常消息流是异步的。MQTT 另外一个需要提及的是其在客户端使用是非常简单的。多数的发布/订阅系统都会在代理端有大量的业务逻辑,但是 MQTT 本质上只是一个订阅和发布系统,这使得其能否在一些小型或者受限的设备上提供一个轻量级的协议实现。

第 7 段(可获 3.19 积分)

MQTT使用基于主题的消息过滤。所以每个消息都包含一个主题,代理用此找出订阅该消息的客户端。更多与主题相关的细节参看MQTT基础入门第五部分。用HiveMQ MQTT代理与其自定义插件系统也可以实现基于内容的过滤。

为了从整体上处理发布/订阅系统的挑战,MQTT提供了服务质量(QoS) 等级。可以轻易的指定消息成功地从客户端传递给代理或从代理到客户端。但也有可能没人订阅与此相关的主题。如何解决此类情况取决于代理。例如,HiveMQ MQTT代理有一个插件系统,它能够识别此类情况并做出处理或者仅仅把每条消息记录至数据库中做为历史分析。为了降低主题的僵化性,重点要仔细设计主体树并为将来用例扩展预留空间。如果你遵循这些方针,MQTT便可完美投入使用。

第 8 段(可获 2.58 积分)

与消息队列的区别

关于MQTT有很多困惑,它的名称以及它是否是用消息队列实现的。我们将阐明这些困惑并说明他们的差异。在上一篇文章中我们已经指出,MQTT名字来自一个名为MQseries的IBM产品,与“消息队列”无关。那抛开名称的困惑,MQTT和传统消息队列之间还有何区别?

消息队列存储消息,直到它们被消费
使用消息队列时,每个传入的消息将被存储在该队列中,直到它被任意客户端取走(通常称为消费者)。否则,消息将被卡在队列中等待被消费。它不可能像在MQTT中没人订阅主题那样,可以不被任何客户端处理。

第 9 段(可获 1.89 积分)

消息只会被一个客户所消费
另一个大的区别是,在传统队列中,消息只由一个消费者处理。使得负载可以分布到特定队列的所有用户上。在MQTT中这恰恰相反,每个订阅该主题的订阅者都将获得此消息。

队列是命名的并且必须显式创建
队列远不及主题灵活。在使用队列之前,必须用单独的命令显式创建队列。队列创建后才可能发布或者消费消息。在MQTT中,主题非常灵活,可以在运行时创建。

第 10 段(可获 1.44 积分)

如果还有其它被我们所遗漏的差异,我们很期待你的评论。

第二篇文章到此就结束了,下周我们将更多的探讨MQTT客户端和代理的定义以及它们之间连接的建立。

如果你想在下一篇文章发布后立刻收到通知,只需注册我们的newsletter,它会每周为你带来关于MQTT和HiveMQ的新内容。如果你喜欢RSS,你可以点击这里订阅我们的RSS.

第 11 段(可获 1.19 积分)

文章评论