返回介绍

消息传递系统的基本原理

发布于 2025-01-25 22:50:16 字数 4539 浏览 0 评论 0 收藏 0

在谈论消息和消息传递系统时,需要考虑四个基本要素,如下:

  • 通信的方向,可以是单向的,也可以是双向的
  • 消息的目的地,这也决定了消息的内容
  • 消息的时间,这决定了消息是否可以被立即发送和接收(同步),也可以在将来接收(异步)
  • 信息的传递方式,直接传递或通过一个中介者进行传递

在接下来的部分中,我们将把这些方面正式化,以便为我们稍后的讨论奠定基础。

单向通信和请求/回复模式

消息传递系统中最基本的方面是通信的传递方向,这个方向通常也表示了这条消息的含义。

最简单的消息传递模式是消息从源到目的地单向推送; 这是一个简单的情况,并不需要太多解释:

单向通信的一个典型例子是使用 WebSockets 向连接的浏览器或 Web 服务器发送消息的电子邮件,或将任务分配给一组工作人员的系统。

然而,请求/回复模式比单向通信更受欢迎;一个典型的例子就是调用 Web 服务。下图显示了这个简单且众所周知的场景:

请求/回复模式可能看起来是一个简单的模式; 但是,当通信异步或涉及多个节点时,我们将看到它变得更加复杂。看看下图中的例子:

通过上图所示的设置,我们可以理解一些请求/回复模式的复杂性。如果我们考虑任何两个节点之间的通信方向,我们可以肯定地说它是单向的。但是,从全局角度来看,发起者发送一个请求,然后接收一个关联的响应,即使来自不同的节点。在这些情况下,真正区分请求/响应模式与单向消息传递模式的区别在于请求和响应之间的关系,它保存在发起者中。回复通常在请求的相同上下文中处理。

消息类型

一条消息本质上是连接不同软件组件的一种方式,这样做的原因有很多:这可能是因为我们想要获得由另一个系统或组件持有的某些信息,或远程执行某项操作,或向某个组件通知某操作刚刚发生。消息内容也会因通信原因而异。 一般来说,我们可以根据消息的目的来确定三种类型的消息:

  • 命令消息
  • 事件消息
  • 文档消息

命令消息

命令消息对我们来说已经很熟悉;它本质上是一个序列化的 command 对象,正如我们在 Chapter 6-Design Patterns 中所描述的那样。 这种类型的消息的目的是触发 recevier 上的动作或任务的执行。为了做到这一点,我们的信息必须包含运行任务的基本信息,这通常是操作的名称和执行时提供的参数列表。 命令消息可用于实现远程过程调用( RPC )系统,分布式计算或更简单地用于请求某些数据。 RESTful HTTP 调用是命令消息的简单示例; 每个 HTTP 请求都有一个特定的含义,并与一个精确的操作相关联:例如 GET 表示检索资源; POST 表示创建一个新的资源; PUT 表示更新一个资源; DELETE 表示删除一个资源。

事件消息

事件消息用于通知另一个组件发生了某些事件。它通常包含事件的类型,有时还包含一些细节,如 contextsubjectactor 。 在 Web 开发中,当使用长轮询或 WebSocket 接收来自服务器的刚刚发生的事件的通知时,我们在浏览器中使用事件消息,例如数据的变化导致一个时间的发生。事件的使用是分布式应用程序中非常重要的机制,因为它使我们能够将系统的所有节点保持在同一状态上。

文档消息

文档消息主要用于在组件和机器之间传输数据。区分文档消息和命令消息(可能还包含数据)的主要特点是该消息不包含告诉接收方如何处理数据的任何信息。另一方面,与事件消息的主要区别主要是缺少与特定事件的关联。通常,对命令消息的回复是文档消息,因为它们通常只包含请求的数据或操作的结果。

异步消息传递和队列

作为 Node.js 开发人员,我们应该已经知道执行异步操作的优势。对于消息和通信而言,这是一回事。

我们可以将同步通信与电话进行比较:两个对等设备必须同时连接到同一个通道,并且它们应该实时交换消息。通常情况下,如果我们想打电话给其他人,我们可能需要另一部手机或关闭正在进行的通信以便开始新的通话。

异步通信类似于 SMS :它不要求收件人在我们发送邮件时连接到网络,我们可能会立即收到回复或者收到未知延迟后的回复,或者我们可能根本没有收到回复。我们可能会将多个 SMS 一个接一个地发送给多个收件人,并以任何顺序收到他们的回复(如果有)。简而言之,我们使用更少的资源可以获得更好的并行性。

异步通信的另一个重要优点是可以将消息存储并尽快或稍后发送。当接收器太忙而无法处理新消息或我们希望保证传送时,这可能很有用。在消息传递系统中,这可以使用消息队列实现,该消息队列调解发送者和接收者之间的通信,在将消息传递到其目标之前存储任何消息,如下图所示:

如果出于任何原因接收机崩溃,与网络断开连接或速度变慢,则消息会在队列中累积并在接收机联机并且完全正常工作时才可以让发送者继续请求并调度。队列可以位于发送者中,也可以在发送者和接收者之间分开,或者存储在充当通信中间件的专用外部系统中。

点对点或基于代理的消息传递

消息可以以对等方式直接传送给接收方,也可以通过称为消息代理的集中式中介系统传送。代理的主要作用是将发件人的信息接收者分离出来。下图显示了两种方法之间的架构差异:

在对等体系结构中,每个节点都直接负责将消息传递给接收方。这意味着节点必须知道接收方的地址和端口,他们必须就协议和消息格式达成一致。代理从等式中消除了这些复杂性:每个节点都可以完全独立,并且可以与未定义数量的对等进行通信,而无需直接了解其详细信息。 代理还可以充当不同通信协议之间的桥梁,例如, RabbitMQ broker 支持高级消息队列协议( AMQP ),消息队列遥测传输( MQTT )和 简单/流式文本定向消息协议( STOMP ),支持不同消息协议的多个应用程序进行交互。

MQTT 是一种轻量级消息传递协议,专为机器间通信(物联网)设计。 AMQP 是一个更复杂的协议,旨在成为专有消息中间件的开源替代品。 STOMP 是一个轻量级的基于文本的协议,来自 HTTP school of design 。 这三个都是应用层协议,并且基于 TCP / IP

除了解耦和互操作性外,代理还可以提供更多高级功能,如持久队列,路由,消息转换和监控,而不提及许多代理支持的广泛的消息传递模式。当然,没有任何东西可以阻止我们使用对等体系结构实现所有这些功能,但不幸的是,还需要付出更多努力。尽管如此,避免使用代理的原因可能有所不同:

  • 代理可能发生故障
  • 代理必须扩展,而在对等体系结构中,我们只需要扩展单个节点
  • 在没有代理的情况下交换消息可以大大减少传输的延迟

如果我们想要实现一个对等消息传递系统,我们也拥有更多的灵活性和能力,因为我们不受任何特定技术,协议或体系结构的约束。 ØMQ 是一个构建消息传递系统的库,其流行性很好地证明了我们可以通过构建定制的对等或混合体系结构获得灵活性。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文