In distributed systems, communication between various applications plays an important role. Effectively passing messages between applications was always a crucial decision in system design. One of the elegant solutions to pass messages around your distributed system is a message broker.
在分布式系统中,各种应用程序之间的通信起着重要的作用。 在应用程序之间有效地传递消息始终是系统设计中的关键决定。 消息代理是在分布式系统中传递消息的一种优雅解决方案。
In distributed systems, communication between various applications plays an important role. Effectively passing messages between applications was always a crucial decision in system design. One of the elegant solutions to pass messages around your distributed system is a message broker.
在分布式系统中,各种应用程序之间的通信起着重要的作用。 在应用程序之间有效地传递消息始终是系统设计中的关键决定。 消息代理是在分布式系统中传递消息的一种优雅解决方案。
They bring in decoupling between the applications and provide an effective way to communicate. With message brokers, an application needs no prior knowledge of their recipients to communicate.
它们带来了应用程序之间的解耦,并提供了一种有效的通信方式。 使用消息代理,应用程序不需要其收件人的先验知识即可进行通信。
However, what is RabbtiMQ? How does RabbitMQ fit in this picture? Also, what is AMQP?
但是,什么是RabbtiMQ? RabbitMQ如何适合此图片? 另外,什么是AMQP?
By the end of this article, we will be able to answer these questions. I also added a few animations so that you can visualize RabbitMQ concepts.
在本文末尾,我们将能够回答这些问题。 我还添加了一些动画,以便您可以可视化RabbitMQ概念。
So are you excited? I am! If you ever had difficulties understanding message brokers, as I did, then this article is the right place to start your journey. Stay with me ?
那你兴奋吗? 我是! 如果像我一样,您在理解消息代理方面遇到困难,那么本文是开始您的旅程的正确地方。 跟我在一起 ?
In general, a broker is a person who facilitates trades between a buyer and a seller. An example could be a real estate agent or a stockbroker.
通常,经纪人是促进买卖双方之间交易的人。 一个例子可以是房地产经纪人或股票经纪人。
Similarly, if we want to trade messages between two distributed software components, we need a mediator. This mediator is known as the message broker. It receives incoming messages from a sender and sends them to a recipient. This way the sender and receiver can be totally isolated.
同样,如果要在两个分布式软件组件之间交换消息,则需要一个中介器。 该介体称为消息代理。 它接收来自发件人的传入消息,并将其发送给收件人。 这样,发送方和接收方可以完全隔离。
Another analogy for a message broker can be a Post Office (see Figure 1). Let’s take a scenario where you are going to send a letter to your cousin living in another city. Then as per this analogy, you are a producer, your cousin is a consumer, and the post office is a message broker.
消息代理的另一个类推可以是邮局(见图1)。 让我们设想一个场景,您要向住在另一个城市的堂兄寄一封信。 然后按照这个比喻,您是生产者,您的表弟是消费者,邮局是消息代理。
Now we know that the purpose of a message broker is to route messages from a producer to a consumer. Let’s examine one such message broker — RabbitMQ. It’s one of the most extensively used message brokers these days.
现在我们知道消息代理的目的是将消息从生产者路由到消费者。 让我们研究一个这样的消息代理-RabbitMQ。 它是当今使用最广泛的消息代理之一。
The way RabbitMQ routes messages depends upon the messaging protocol it implements. RabbitMQ supports multiple messaging protocols. However, the one we are interested in is AMQP. It is an acronym for Advanced Message Queuing Protocol.
RabbitMQ路由消息的方式取决于它实现的消息协议。 RabbitMQ支持多种消息传递协议。 但是,我们感兴趣的是AMQP。 它是高级消息队列协议的缩写。
So without any further ado let’s have a closer look at the AMQP protocol model.
因此,事不宜迟,让我们仔细看看AMQP协议模型。
The conceptual model of AMQP is quite simple and straightforward. It has three entities:
AMQP的概念模型非常简单明了。 它具有三个实体:
When a publisher pushes a message to RabbitMQ, it first arrives at an exchange. The exchange then distributes copies of these messages to variously connected queues. Finally, consumers receive these messages.
当发布者将消息推送到RabbitMQ时,它首先到达交换处。 然后,交换机将这些消息的副本分发到各个连接的队列中。 最终,消费者收到这些消息。
Consider a message as a piece of data. It is necessarily a package with a payload and some meta-data. The payload contains full data whereas meta-data are properties used by RabbitMQ.
将一条消息视为一条数据。 它必须是带有有效负载和一些元数据的程序包。 有效负载包含完整数据,而元数据是RabbitMQ使用的属性。
Figure 2 depicts a graphical representation of the AMQP model.
图2描绘了AMQP模型的图形表示。
AMQP is a programmable protocol. Programmers have the liberty to use libraries to configure entities (exchange, binding, and queue) as per their own needs. A RabbitMQ admin has no role in setting up these entities.
AMQP是可编程协议。 程序员可以根据自己的需要使用库来配置实体(交换,绑定和队列)。 RabbitMQ管理员在设置这些实体方面不起作用。
There are plenty of libraries available to work with RabbitMQ. You can choose from Nodejs, Python, .Net, Java, and many more.
有许多库可用于RabbitMQ。 您可以选择Nodejs , Python ,。 Net , Java等。
These queues are somehow similar to the queues from our data structure classes. RabbitMQ queues also follow FIFO — First-In-First-Out methodology. A queue is a place where RabbitMQ stores messages/data.
这些队列在某种程度上类似于我们数据结构类中的队列。 RabbitMQ队列还遵循FIFO(先进先出方法)。 队列是RabbitMQ存储消息/数据的地方。
Programmers can configure queues through available programming libraries. You can make a queue durable ( with the Durability
property) to safeguard your data in case the broker crashes. You can also provide a name(with the Name
property) to a queue. Other than Name
and Durability
, a queue has a few other properties like auto-delete, exclusive, and arguments.
程序员可以通过可用的编程库配置队列。 您可以使队列具有持久性(使用Durability
属性),以保护您的数据,以防代理崩溃。 您还可以为队列提供一个名称(带有Name
属性)。 除了Name
和Durability
,队列还具有其他一些属性,例如自动删除,独占和参数。
Before moving any further, it’s important to understand who is a direct consumer of these queues. Moreover, how many ways can a user consume messages from a queue?
在继续进行之前,了解谁是这些队列的直接使用者很重要。 此外,用户可以用几种方式使用队列中的消息?
Consumers are the ones who are going to use messages stored in a queue. It is possible to connect more than one consumer to a queue at a time. Consumers can either pull the message from the queue by pooling it or queues can even push the message to various connect consumers.
消费者是将要使用存储在队列中的消息的消费者。 一次可以将一个以上的使用者连接到一个队列。 使用者可以通过将消息池化来从队列中拉出消息,或者队列甚至可以将消息推送到各个连接使用者。
Bindings are the rules that a queue defines while establishing a connection with an exchange. You can have a queue connected to multiple exchanges. Every queue is also connected to a default exchange. An exchange will use these bindings to route messages to queues.
绑定是队列在与交换机建立连接时定义的规则。 您可以将一个队列连接到多个交换机。 每个队列也都连接到默认交换机。 交换将使用这些绑定将消息路由到队列。
An Exchange is a gateway to RabbitMQ for your messages. The distance the message has to travel inside RabbitMQ depends on the type of exchange. Primarily there are four types.
Exchange是通往RabbitMQ发送邮件的网关。 消息在RabbitMQ中必须经过的距离取决于交换的类型。 主要有四种类型。
The name explains it all! — A direct exchange delivers a message directly to the queues that satisfy the below condition:
名称说明了一切! —直接交换将消息直接传递到满足以下条件的队列:
Routing key == Binding key
A routing key is an attribute of the message. On the other hand, a binding key is something you specify while creating a binding between a queue and an exchange.
路由密钥是消息的属性。 另一方面,绑定密钥是在队列和交换之间创建绑定时指定的。
Figure 3 is a visual explanation of how messages flow while using a direct exchange.
图3是使用直接交换时消息如何流动的直观说明。
A message originates from a producer (green circle) with a routing key — img.resize
. Once it reaches the exchange (Orange circle), the exchange will try to find all queues with binding key — img.resize
. In case of a match, the message is pushed to all matched queues (resize in our case). If there is no match found, the message can be sent back to the producer or can even be discarded. We are lucky that we found a match in our example ?
消息源自带有路由键img.resize
的生产者(绿色圆圈)。 一旦到达交换中心(橙色圆圈),交换中心将尝试查找所有具有绑定键img.resize
队列。 如果匹配,则消息被推送到所有匹配的队列(在我们的例子中是调整大小)。 如果找不到匹配项,则可以将消息发送回生产者,甚至可以丢弃。 我们很幸运在我们的示例中找到了一个匹配项?
[gif image]
[gif图片]
Once the message reaches the desired queue (resize in our case), they are distributed in round-robin fashion to all the connected consumers (resizer.1/resizer.2 in our case).
一旦消息到达所需的队列(在本例中为调整大小),它们便以循环方式分发给所有连接的使用者(在本例中为resizer.1 / resizer.2)。
By distributing messages in a round-robin fashion, RabbitMQ makes sure that the messages are load balanced.
通过以循环方式分发消息,RabbitMQ确保消息是负载均衡的。
You must have noticed that the queue named crop is not receiving any messages. Because the routing key in this example is img.resize
. To send messages to this queue, we need to send messages with a routing key that would match the binding key (say img.crop
for instance).
您必须已经注意到,名为crop的队列未收到任何消息。 因为此示例中的路由键是img.resize
。 要将消息发送到此队列,我们需要使用路由键与绑定键匹配的消息发送消息(例如img.crop
)。
A Fanout exchange ignores routing keys and distributes a message to all the connected queues. No wonder it is called Fanout (blowing messages to all connected queues! ?).
扇出交换机忽略路由键,并将消息分发到所有连接的队列。 难怪它被称为“扇出”(向所有连接的队列发送消息!)。
One of the use cases for this type of exchange is message broadcast.
这种类型的交换的用例之一是消息广播。
Please note that RabbitMQ will still do round robin if there is more than one consumer of the queue.
请注意,如果队列中有多个使用者,RabbitMQ仍将进行循环。
A topic exchange routes a message by matching routing key with a pattern in the binding key.
主题交换通过将路由键与绑定键中的模式进行匹配来路由消息。
Routing key == Pattern in binding key.
RabbitMQ uses two wild card characters for pattern matching *
and #
. Use a *
to match 1 word and a #
to match 0 or more words.
RabbitMQ使用两个通配符来进行模式匹配*
和#
。 使用*
匹配1个单词,使用#
匹配0个或更多单词。
Figure 5 is a visual depiction of a topic exchange. Messages with routing key — logs.error
will match patterns — logs.error
and logs.*
. Hence these messages will end up in the queues — only error
and all logs
.
图5是主题交换的可视化描述。 带有路由键的消息logs.error
将匹配模式logs.error
和logs.*
。 因此,这些消息将最终进入队列- only error
和all logs
。
Whereas for the producer at the bottom-left, messages with routing key— logs.success
will match patterns of binding key #success
and logs.*
. Hence these messages will end up in the queues — all logs
and only success
.
对于左下角的生产者,带有路由键的消息logs.success
将匹配绑定键#success
和logs.*
。 因此,这些消息将最终进入队列- all logs
, only success
。
[gif]
[gif]
This type of exchange has a vast range of use cases. It can be used in the publish-subscribe pattern, distributing relevant data to desiring workers processes and many more.
这种类型的交换具有广泛的用例。 它可以用于发布-订阅模式,将相关数据分发到所需的工作进程等。
A header is a particular type of exchange that routes messages based on keys present in the message header. It overlooks routing key attribute of the message.
头是一种特殊类型的交换,它根据消息头中存在的密钥来路由消息。 它忽略了消息的路由键属性。
When creating bindings for a header exchange, it is possible to bind a queue to match more than one header. In such a case, RabbitMQ should know from the producer if it should match all or any of these keys.
当创建用于标题交换的绑定时,可以绑定一个队列以匹配多个标题。 在这种情况下,RabbitMQ应该从生产者那里知道它是否应该匹配所有或所有这些密钥。
A producer/application can do this by providing an extra flag called ‘x-match’. ‘x-match’ can have any
or all
values. The first one mandates that only one value should match while the latter mandates that all must match.
生产者/应用程序可以通过提供一个额外的标记“ x-match”来做到这一点。 “ x-match”可以具有any
或all
值。 第一个要求只有一个值应该匹配,而第二个要求所有值都必须匹配。
Once a message reaches its destination, the broker should delete the message from the queue. It is necessary because a queue overflow can occur if it keeps accumulating messages.
消息到达目的地后,代理应从队列中删除消息。 这是必要的,因为如果持续累积消息,则可能会发生队列溢出。
Before deleting any message, the broker must have a delivery acknowledgment. There are two possible ways to acknowledge message delivery.
在删除任何消息之前,代理必须具有传递确认。 有两种可能的方式来确认消息传递。
In most cases, explicit acknowledgment is used as it makes sure that the consumer has consumed the message without any failover.
在大多数情况下,使用显式确认,因为它可以确保使用者使用了该消息而没有任何故障转移。
RabbitMQ is a very mature and useful product. This article is only a high-level introduction to RabbitMQ. I simplified the concepts to provide a reference point for you to move further. Visit the RabbitMQ website for more complex topics.
RabbitMQ是非常成熟且有用的产品。 本文只是RabbitMQ的高级介绍。 我简化了概念,为您提供进一步的参考。 访问RabbitMQ网站以获取更复杂的主题。
Hope you like the article. Don’t forget to clap(or applaud ?). Follow to read my upcoming stories. Until next time, keep Queuing.
希望你喜欢这篇文章。 不要忘记鼓掌(或鼓掌?)。 继续阅读我即将发表的故事。 在下一次之前,请保持排队。
翻译自: https://www.freecodecamp.org/news/rabbitmq-9e8f78194993/