1. 概述
为了更好地理解 RabbitMQ 的工作原理,我们需要深入研究它的核心组件。
在本文中,我们将研究交换器、队列和绑定,以及如何在 Java 应用程序中以编程方式声明它们。
2. 设置
像往常一样,我们将使用 Java 客户端和 RabbitMQ 服务器的官方客户端。
首先,我们为 RabbitMQ 客户端添加 Maven 依赖项:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.12.0</version>
</dependency>
接下来,我们声明与 RabbitMQ 服务器的连接并打开通信通道:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
此外,更详细的设置示例可以在我们的RabbitMQ 简介中找到。
3. 交流
在 RabbitMQ 中, 生产者从不直接将消息发送到队列 。相反,它使用交换机作为路由中介。
因此,交换器决定消息是否进入一个队列、多个队列,或者只是被丢弃。
例如,根据路由策略,我们有 四种交换类型可供选择 :
- 直接 – 交换机根据路由键将消息转发到队列
- Fanout – 交换器忽略路由键并将消息转发到所有有界队列
- 主题 – 交换器使用交换器上定义的模式与附加到队列的路由键之间的匹配将消息路由到有界队列
- 标头 – 在这种情况下,使用消息标头属性而不是路由键将交换器绑定到一个或多个队列
此外, 我们还需要声明交换的属性 :
- 名称 – 交易所的名称
- 持久性 – 如果启用,经纪商将不会在重启时删除交易所
- 自动删除 – 启用此选项后,如果交换未绑定到队列,代理将删除交换
- 可选参数
考虑到所有因素,让我们声明交换的可选参数:
Map<String, Object> exchangeArguments = new HashMap<>();
exchangeArguments.put("alternate-exchange", "orders-alternate-exchange");
当传递 替代交换 参数时,交换将未路由的消息重定向到替代交换 ,正如我们从参数名称中猜测的那样。
接下来, 让我们声明一个启用持久性并禁用自动删除的直接交换 :
channel.exchangeDeclare("orders-direct-exchange", BuiltinExchangeType.DIRECT, true, false, exchangeArguments);
4. 队列
与其他消息代理类似,RabbitMQ 队列 基于 FIFO 模型将消息传递给消费者 。
另外,在创建队列时, 我们可以定义队列的几个属性 :
- 名称 – 队列的名称。如果未定义,代理将生成一个
- 持久性 – 如果启用,代理在重新启动时不会删除队列
- Exclusive – 如果启用,队列将仅被一个连接使用,并在连接关闭时被删除
- 自动删除 – 如果启用,代理会在最后一个消费者取消订阅时删除队列
- 可选参数
此外,我们将声明队列的可选参数。
让我们添加两个参数:消息 TTL 和最大优先级数:
Map<String, Object> queueArguments = new HashMap<>();
queueArguments.put("x-message-ttl", 60000);
queueArguments.put("x-max-priority", 10);
现在,让我们 声明一个禁用独占和自动删除属性的持久队列 :
channel.queueDeclare("orders-queue", true, false, false, queueArguments);
5. 绑定
交换器使用绑定将消息路由到特定队列。
有时,它们附有一个路由密钥,某些类型的交换器使用该路由密钥来过滤特定消息并将其路由到有界队列。
最后,让 我们使用路由键将我们创建的队列绑定到交换器 :
channel.queueBind("orders-queue", "orders-direct-exchange", "orders-routing-key");
六,结论
在本文中,我们介绍了 RabbitMQ 的核心组件——交换、主题和绑定。我们还了解了它们在消息传递中的作用以及如何从 Java 应用程序管理它们。
与往常一样,本教程的完整源代码可在 GitHub 上获取。