Architectural Messaging Patterns
Contents
Original: Architectural messaging patterns: an illustrated guide
本文主要讲解消息交换系统的一些主要的架构模式以及路由的方法,主要涉及像 Redis、Apache Kafka、RabbitMQ、ZeroMQ 和 IBM MQ 等软件。同时说明这些模式是如何有效地降低架构师和开发者间沟通成本。
在概念上讲,消息是指一个发送者和一个或多个接收者之间的信息交换。从早期大型机时代开始,消息交换就是计算机编程和架构设计中的一个重要组成部分。
经过多年的发展,消息交换演化成了几种成熟的模式。通过这篇文章,笔者将介绍其中一些使用比较广泛的模式。我将它们分成了两个章节。第一章为消息交换架构,讲述消息在发送者与接收者之间传递的形式。第二章是路由,讲述发送者将消息传递给接收者的逻辑。
消息交换架构
这一章主要讲述关于消息传输机制的一些模式
发布订阅 Pub-Sub
Pub-Sub 是一种通过代理 Message Broker 向指定主题 Topic 发送消息的一种模式。你可以把主题 Topic 想像成收件箱 Inbox 。收件箱的概念在不同的软件中叫法可能不一样。比如,RabbitMQ 称它的收件箱为 Exchange,而 Kafka 则称它为 Topic。接收者通过绑定定到 Topic 的方式,异步地接收相关的消息。
Pub-Sub 模式的好处是简单易懂,消息一进一出。另外,由于它是异步的,消息在发送者和接收者之间传递时不存在锁的问题。发送者将消息交给代理后就可以继续干别的事情去了。然后接收者在它方便的时候再自行去接收消息。使用 Pub-Sub 模式传递的消息一般独立性会比较强,会包含处理该消息所需要的全部信息。
散播 Fanout
Fanout 类似于 Pub-Sub,都是基于 Topic 进行消息交换,不同的是 Fanout 模式下,多个接收者会订阅同一个 Topic。然后,当消息被发送到这个 Topic 时,所有接受者都将收到该消息。相当于消息被散播出去了。
Twitter 就是非常典型的 Fanout 模式。用户发的每个 tweet 都会被推送到他的粉丝那里。
单向流 Unidirectional streaming
单向流模式是指发送者会不停地给接收者发送数据。发送者很可能明确地知道收接者会是谁,比如手机通过网络不停地向某个服务器发送GPS位置
或者, 发送者也可以通过代理技术,将流通过某种 topic/inbox 机制将流转发给接收者。
Apache Kafka 就使用了该技术来实现单向流
双向流
同单向流,不过多了一条反向流,接收者可以反向地给发送者发送信息。
举个双向流的例子:gRPC。gRPC 基于 HTTP/2, 它允许服务器和客户端建立一个持久的连接。一旦连接完成,数据可以在服务器和客户端之间双向发送。(另外一个例子:websocket)
路由
这一章列出在消息交换中,不同的消息由路方式。不同于 Pub-Sub, Fanout 和 Streaming 这些主要解决架构问题,Unicast 单播,Broadcast 广播 和 Multicast 多播, 以及 Anycast 模式解决的是物理链路的问题。
单播 Unicast
发送者,比如一个浏览器,发送一个请求消息给一个网络上某个特定的服务器。互联网的路由机制知道如何找到这个服务器并把请求送到上面。然后,服务器又通过相同的路由机制将响应发回到浏览器上。
广播 Broadcast
广播模式下,发送者发出的消息将会被网络中所有接收者收到。网络中的路由器负责发现网络中所有的设备以及投递相应的消息。
比较典型的例子是 ARP,在 ARP 协议中,路由知道网络中所有设备的物理 MAC 地址和对应的 IP 地址,因而可以完成消息的转发。
多播 Multicast
多播模式下,送者可以指定将消息发送给特定的一组接收者。这个组可以通过网络中设备的类型或者网段来做切分。
比如 IPTV 就是典型的多播模式,IPTV 的数据会被串流到连接至某一特定频道(Channel)的设备上,另外还有像 Fackbook 的直播,或者网络会议也是多播的模式。
Anycast
Anycast 模式下,路由器会将消息发送给符合一定条件的接收者。 Anycast 模式的语义大概是: “请将这个消息发送给任何符合这些条件的接收者”。最典型的 Anycast 应用场景是将消息发送给某一地理区域的接收者。
CDN 技术使用了 Anycast 模式,所谓的 CDN ,就是使得发送者可以从最接近它的服务器上接收数据。
总结
如果你是一位常年和消息系统打交道的工程师或构架师,上面提到的这些模式对你来讲都不陌生。虽然具体术语可能稍有区别,但是本质上都是一样的东西。
将这些模式用通用的名称统一起来有一个好处,就是工程师和架构师在交流时可以明确的知道对方讲的是什么玩意。使用约定好的名称可以节省大量的时间。比如在开会时,我们讲“这个业务逻辑使用Pub-Sub模式更好”,比套用具体的实现逻辑去解释自己的想法,显然是要简单得多的。前提是要与会的所有人都明白这个术语背后代表的是什么。我写这篇文章是想进一点绵薄之力,让大家对这些应用比较广泛的模式有一个共识。
Author Klesh Wong
LastMod 2021-05-05