Exchanges, Queues, and Bindings in RabbitMQ – RabbitMQ中的交换、队列和绑定

最后修改: 2021年 6月 24日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

To better understand how RabbitMQ works, we need to dive into its core components.

为了更好地了解 RabbitMQ 如何工作,我们需要深入了解其核心组件。

In this article, we’ll take a look into exchanges, queues, and bindings, and how we can declare them programmatically within a Java application.

在这篇文章中,我们将了解一下交换、队列和绑定,以及我们如何在Java应用程序中以编程方式声明它们。

2. Setup

2.设置

As usual, we’ll use the Java client and the official client for the RabbitMQ server.

像往常一样,我们将使用 Java 客户端和 RabbitMQ 服务器的官方客户端。

First, let’s add the Maven dependency for the RabbitMQ client:

首先,让我们添加RabbitMQ客户端的Maven依赖项

<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.12.0</version>
</dependency>

Next, let’s declare the connection to the RabbitMQ server and open a communication channel:

接下来,让我们声明与 RabbitMQ 服务器的连接并打开一个通信通道。

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

Also, a more detailed example of the setup can be found in our Introduction to RabbitMQ.

此外,可以在我们的RabbitMQ 介绍中找到一个更详细的设置示例。

3. Exchanges

3.交流会

In RabbitMQ, a producer never sends a message directly to a queue. Instead, it uses an exchange as a routing mediator.

在 RabbitMQ 中,生产者从不直接向队列发送消息。相反,它使用一个交换器作为路由调解器。

Therefore, the exchange decides if the message goes to one queue, to multiple queues, or is simply discarded.

因此,交换决定消息是否进入一个队列、多个队列或直接被丢弃。

For instance, depending on the routing strategy, we have four exchange types to choose from:

例如,根据路由策略,我们有四种交换类型可供选择

  • Direct – the exchange forwards the message to a queue based on a routing key
  • Fanout – the exchange ignores the routing key and forwards the message to all bounded queues
  • Topic – the exchange routes the message to bounded queues using the match between a pattern defined on the exchange and the routing keys attached to the queues
  • Headers – in this case, the message header attributes are used, instead of the routing key, to bind an exchange to one or more queues

Moreover, we also need to declare properties of the exchange:

此外,我们还需要声明交易所的属性

  • Name – the name of the exchange
  • Durability – if enabled, the broker will not remove the exchange in case of a restart
  • Auto-Delete – when this option is enabled, the broker deletes the exchange if it is not bound to a queue
  • Optional arguments

All things considered, let’s declare the optional arguments for the exchange:

考虑到所有的事情,让我们宣布交换的可选参数。

Map<String, Object> exchangeArguments = new HashMap<>();
exchangeArguments.put("alternate-exchange", "orders-alternate-exchange");

When passing the alternate-exchange argument, the exchange redirects unrouted messages to an alternative exchange, as we might guess from the argument name.

当传递alternate-exchange参数时,交易所将未被路由的消息重定向到另一个交易所,正如我们可能从参数名称中猜到的那样。

Next, let’s declare a direct exchange with durability enabled and auto-delete disabled:

接下来,让我们声明一个直接交换,启用耐久性,禁用自动删除

channel.exchangeDeclare("orders-direct-exchange", BuiltinExchangeType.DIRECT, true, false, exchangeArguments);

4. Queues

4.尾巴

Similar to other messaging brokers, the RabbitMQ queues deliver messages to consumers based on a FIFO model.

与其他消息传递代理类似,RabbitMQ 队列基于 FIFO 模型将消息传递给消费者

In addition, when creating a queue, we can define several properties of the queue:

此外,在创建一个队列时,我们可以定义队列的几个属性

  • Name – the name of the queue. If not defined, the broker will generate one
  • Durability – if enabled, the broker will not remove the queue in case of a restart
  • Exclusive – if enabled, the queue will only be used by one connection and will be removed when the connection is closed
  • Auto-delete – if enabled, the broker deletes the queue when the last consumer unsubscribes
  • Optional arguments

Further, we’ll declare the optional arguments for the queue.

此外,我们将声明队列的可选参数。

Let’s add two arguments, the message TTL and the maximum number of priorities:

让我们添加两个参数,信息TTL和最大优先级数。

Map<String, Object> queueArguments = new HashMap<>();
queueArguments.put("x-message-ttl", 60000);
queueArguments.put("x-max-priority", 10);

Now, let’s declare a durable queue with the exclusive and auto-delete properties disabled:

现在,让我们声明一个持久队列,禁用独占和自动删除属性

channel.queueDeclare("orders-queue", true, false, false, queueArguments);

5. Bindings

5. 捆绑

Exchanges use bindings to route messages to specific queues.

交换使用绑定将消息路由到特定队列。

Sometimes, they have a routing key attached to them, used by some types of exchanges to filter specific messages and route them to the bounded queue.

有时,它们有一个附加的路由键,被某些类型的交换所用来过滤特定的消息,并将它们路由到有界队列。

Finally, let’s bind the queue that we created to the exchange using a routing key:

最后,让我们使用路由密钥将我们创建的队列绑定到交易所

channel.queueBind("orders-queue", "orders-direct-exchange", "orders-routing-key");

6. Conclusion

6.结语

In this article, we covered the core components of RabbitMQ – exchanges, topics, and bindings. We also learned about their role in message delivery and how we can manage them from a Java application.

在这篇文章中,我们介绍了 RabbitMQ 的核心组件 – 交换、主题和绑定。我们还了解了它们在消息传递中的作用以及我们如何从一个 Java 应用程序中管理它们。

As always, the complete source code for this tutorial is available over on GitHub.

一如既往,本教程的完整源代码可在GitHub上获取