详解 RabbitMQ 工作模式之通配符模式

在 RabbitMQ 中,通配符模式(Wildcard Pattern) 是一种消息路由的方式,它允许你通过某种模式来匹配多个队列,常用于 主题交换器(topic exchange) 模式下。通配符模式使得消息发布者能够根据特定的模式来指定消息的路由规则,使得多个消费者可以根据匹配的规则来接收消息。

1. RabbitMQ 主题交换器(Topic Exchange)

在 RabbitMQ 中,交换器(Exchange)是用来接收生产者发送的消息并将它们路由到队列的组件。主题交换器(topic exchange) 是四种交换器之一,使用路由键(routing key)来决定消息的路由,而路由键可以使用通配符进行模式匹配。

在 topic exchange 中,生产者发布消息时,会指定一个路由键。消费者可以通过绑定队列时指定一个路由键模式,来接收符合特定模式的消息。

2. 通配符的工作方式

在主题交换器的路由键中,通配符用于匹配不同的路由键模式。常见的通配符有两种:

  • *(星号):匹配一个单词
  • #(井号):匹配零个或多个单词
2.1 *(星号)通配符

* 通配符表示匹配路由键中的单个单词(由点 . 分隔)。例如,如果你定义了路由键 stock.usd.nyse,那么星号通配符 stock.*.nyse 将匹配以下路由键:

  • stock.usd.nyse(匹配)
  • stock.eur.nyse(匹配)
  • stock.jpy.nyse(匹配)

但是,它不会匹配 stock.nyse 或 stock.usd.nyse.newyork,因为这两个路由键并不是由三个部分组成的。

2.2 #(井号)通配符

# 通配符表示匹配零个或多个单词。例如:

  • stock.# 可以匹配所有以 stock 开头的路由键,无论后面跟着多少个单词:
    • stock.usd.nyse(匹配)
    • stock.eur.nyse(匹配)
    • stock.nyse(匹配)
    • stock.usd.nyse.newyork(匹配)
  • #.nyse 可以匹配任何以 .nyse 结尾的路由键,并且可以有任意数量的单词:
    • stock.usd.nyse(匹配)
    • stock.eur.nyse(匹配)
    • stock.nyse(匹配)
    • stock.usd.nyse.newyork(匹配)
  • stock.#.nyse 匹配的路由键需要包括 stock、某个单词、以及 .nyse,如:
    • stock.usd.nyse(匹配)
    • stock.eur.nyse(匹配)
    • stock.usd.nyse.newyork(匹配)
    • stock.usd.nyse.newyork.city(匹配)

3. 示例:使用通配符模式

让我们通过一个简单的示例来进一步理解通配符模式的使用。

假设我们有一个 topic 类型的交换器,名为 exchange.topic,它被绑定到以下队列:

  • queue1:绑定路由键为 stock.*.nyse(匹配所有类型为 nyse 的 stock 消息)
  • queue2:绑定路由键为 stock.usd.#(匹配所有包含 stock.usd 的路由键)
  • queue3:绑定路由键为 #.nyse(匹配所有以 .nyse 结尾的路由键)

3.1 发送消息

生产者发送以下消息到 exchange.topic

  1. 路由键 stock.usd.nyse
  2. 路由键 stock.eur.nyse
  3. 路由键 stock.usd.nyse.newyork
  4. 路由键 stock.jpy.nyse
  5. 路由键 stock.usd.london

3.2 消费者的接收情况

  • queue1(绑定 stock.*.nyse)将接收到路由键为 stock.usd.nysestock.eur.nysestock.jpy.nyse 的消息。
  • queue2(绑定 stock.usd.#)将接收到 stock.usd.nysestock.usd.nyse.newyorkstock.usd.london 的消息。
  • queue3(绑定 #.nyse)将接收到 stock.usd.nysestock.eur.nysestock.usd.nyse.newyorkstock.jpy.nyse 的消息。

4. 实际应用场景

使用通配符模式,你可以根据实际需求定制消息的路由规则,常见的应用场景包括:

  • 股票行情:通过路由键分配不同股票的市场信息(如 stock.usd.nysestock.eur.nyse)。
  • 日志系统:根据服务类型和环境来分类日志(如 logs.info.server1logs.error.server2)。
  • 监控系统:根据监控指标和地区进行消息路由(如 monitoring.cpu.us-eastmonitoring.memory.eu-west)。

5. 配置 RabbitMQ 使用通配符

在 RabbitMQ 的管理界面或配置文件中,您可以通过声明一个 topic 类型的交换器,并使用通配符来绑定队列。以下是如何在代码中配置通配符模式的示例:

// 创建连接和通道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

// 声明交换器(topic 类型)
channel.exchangeDeclare("exchange.topic", "topic");

// 声明队列并绑定
channel.queueDeclare("queue1", false, false, false, null);
channel.queueBind("queue1", "exchange.topic", "stock.*.nyse");

channel.queueDeclare("queue2", false, false, false, null);
channel.queueBind("queue2", "exchange.topic", "stock.usd.#");

channel.queueDeclare("queue3", false, false, false, null);
channel.queueBind("queue3", "exchange.topic", "#.nyse");

// 生产者发送消息
String message = "Stock data";
channel.basicPublish("exchange.topic", "stock.usd.nyse", null, message.getBytes());

在这个例子中,生产者向 exchange.topic 交换器发送消息时,消息将被路由到符合路由键模式的队列。

6. 小结

  • 通配符模式是 RabbitMQ 主题交换器(topic exchange)路由机制的重要组成部分,允许生产者和消费者基于路由键的模式进行消息路由。
  • 通过使用 *(匹配单个单词)和 #(匹配零个或多个单词)通配符,消费者可以灵活地指定他们感兴趣的消息类型。
  • 适当使用通配符可以使消息传递更加高效和灵活,尤其是在需要多种模式匹配的场景下(如日志、监控和股票行情系统)。

通过理解通配符模式并将其应用到 RabbitMQ 中,你可以根据业务需求设计更加灵活的消息传递机制。