RabbitMQ系列学习笔记(十)--通配符模式

文章目录

本文参考:
尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq
RabbitMQ 详解
Centos7环境安装Erlang、RabbitMQ详细过程(配图)

一、通配符模式原理

通配符模式(Topics)是在路由模式的基础上,给队列绑定带通配符的路由关键字,只要消息的 RoutingKey 能实现通配符匹配,就会将消息转发到该队列。通配符模式比路由模式更灵活,通配符模式使用** topic 交换机**。 能按照通配符规则将消息发送给指定队列。

发送到类型是 topic 交换机的消息的 routingkey 不能随意写,必须满足一定的要求,它必须是一个词列表,以点号分隔开。这些词可以是任意的。

比如说:"stock.usd.nyse","nyse.vmw","quick.orange.rabbit" 这种类型的。但这个词列表最多不能超过 255 个字节。

通配符规则如下:

  • 队列设置 RoutingKey 时,"#" 可以匹配任意多个单词,"*" 可以匹配任意一个单词。
  • 消息设置 RoutingKey 时,RoutingKey 由多个单词构成,中间以 "." 分割开。

二、通配符模式实战

上图绑定关系如下:

  • Q1-->绑定的是中间带orange的3个单词的字符串(.orange.)。
  • Q2-->绑定的是最后一个单词是rabbit的3个单词的字符串(..rabbit)以及第一个单词是lazy的多个单词的字符串(lazy.#)。

1、消费者代码

消费者01代码如下:

java 复制代码
/**
 * Description: 通配符模式消费者01
 */
public class ReceiveLogsTopic01 {
    
	private static final String EXCHANGE_NAME = "topic_logs"; 
    
    public static void main(String[] argv) throws Exception {
		Channel channel = RabbitUtils.getChannel(); 
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
		//声明 Q1 队列与绑定关系 
        String queueName="Q1";
		channel.queueDeclare(queueName, false, false, false, null); 
        //绑定关系并指定routingkey
        channel.queueBind(queueName, EXCHANGE_NAME, "*.orange.*");

		System.out.println("等待接收消息.....");

    	//接收消息
        channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("接收队列:" + queueName + "绑定键:" + envelope.getRoutingKey() + ",消息:" + message);
            }
        });
    }
} 

消费者02代码如下:

java 复制代码
/**
 * Description: 通配符模式消费者02
 */
public class ReceiveLogsTopic02 {
    
	private static final String EXCHANGE_NAME = "topic_logs"; 
    
    public static void main(String[] argv) throws Exception {
		Channel channel = RabbitUtils.getChannel(); 
        channel.exchangeDeclare(EXCHANGE_NAME, "topic");
		//声明 Q2 队列与绑定关系 
        String queueName="Q2";
		channel.queueDeclare(queueName, false, false, false, null); 
        //绑定关系并指定routingkey
        channel.queueBind(queueName, EXCHANGE_NAME, "*.*.rabbit");
        channel.queueBind(queueName, EXCHANGE_NAME, "lazy.#");

		System.out.println("等待接收消息.....");

    	//接收消息
        channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("接收队列:" + queueName + "绑定键:" + envelope.getRoutingKey() + ",消息:" + message);
            }
        });
    }
} 

2、生产者代码

java 复制代码
/**
 * Description: 通配符模式消费者02
 */
public class EmitLogTopic {
	private static final String EXCHANGE_NAME = "topic_logs"; 
    public static void main(String[] argv) throws Exception { 
        Channel channel = RabbitUtils.getChannel();

		Map<String, String> bindingKeyMap = new HashMap<>(); 
        bindingKeyMap.put("quick.orange.rabbit","被队列 Q1Q2 接收到"); 
        bindingKeyMap.put("lazy.orange.elephant","被队列 Q1Q2 接收到"); 
		bindingKeyMap.put("quick.orange.fox","被队列 Q1 接收到"); 
        bindingKeyMap.put("lazy.brown.fox","被队列 Q2 接收到");
		bindingKeyMap.put("lazy.pink.rabbit","虽然满足两个绑定但只被队列 Q2 接收一次"); 
		bindingKeyMap.put("quick.brown.fox","不匹配任何绑定不会被任何队列接收到会被丢弃"); 
		bindingKeyMap.put("quick.orange.male.rabbit","是四个单词不匹配任何绑定会被丢弃"); 
		bindingKeyMap.put("lazy.orange.male.rabbit","是四个单词但匹配 Q2");

		for (Map.Entry<String, String> bindingKeyEntry: bindingKeyMap.entrySet()){ 
            String routingKey = bindingKeyEntry.getKey();
			String message = bindingKeyEntry.getValue(); 
            channel.basicPublish(EXCHANGE_NAME,routingKey, null, message.getBytes("UTF-8"));
			System.out.println("生产者发出消息" + message);
		}
	}
}

3、查看运行结果

将两个消费者和一个生产者分别启动:


根据匹配规则,以及预先设置好的预期打印结果可以看到,Q1只接收了应该被Q1接收的三条消息,其他的没有接收,同理Q2也之接收了自己匹配规则之内的。并且可以发现当一条消息的routingkey既能够匹配Q1规则又能够匹配Q2规则时,Q1和Q2都能接收到该条消息。

相关推荐
虫小宝4 小时前
返利app的消息队列架构:基于RabbitMQ的异步通信与解耦实践
分布式·架构·rabbitmq
芜狄4 小时前
UCOSIII移植——学习笔记1
笔记·嵌入式硬件·学习·stm32f103rct6·ucosiii实时操作系统
We....4 小时前
Java分布式编程:RMI机制
java·开发语言·分布式
在未来等你5 小时前
Elasticsearch面试精讲 Day 18:内存管理与JVM调优
大数据·分布式·elasticsearch·搜索引擎·面试
We....5 小时前
Java 分布式缓存实现:结合 RMI 与本地文件缓存
java·分布式·缓存
Chasing__Dreams5 小时前
kafka--基础知识点--5.3--producer事务
分布式·kafka
所愿ღ5 小时前
JavaWeb-Servlet总结及JSP
java·笔记·servlet
小枫编程5 小时前
Spring Boot 调度任务在分布式环境下的坑:任务重复执行与一致性保证
spring boot·分布式·后端
Cellular_Modem笔记5 小时前
5G NR-NTN协议学习系列:NR-NTN介绍(2)
学习·5g·ntn
笨鸟笃行5 小时前
人工智能训练师三级备考笔记
笔记