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 小时前
【RL】Megatron使学习forward_backward_func返回值
学习
Yuer20254 小时前
用 Rust 做分布式查询引擎之前,我先写了一个最小执行 POC
开发语言·分布式·rust
幺零九零零5 小时前
压测学习-JMeter
学习·jmeter
lkbhua莱克瓦245 小时前
基础-函数
开发语言·数据库·笔记·sql·mysql·函数
程途拾光1585 小时前
自监督学习在无标签数据中的潜力释放
人工智能·学习
yuxb735 小时前
Kubernetes核心组件详解与实践:Service
笔记·kubernetes
软件技术NINI5 小时前
JavaScript性能优化实战指南
前端·css·学习·html
Blossom.1186 小时前
多模态大模型LoRA微调实战:从零构建企业级图文检索系统
人工智能·python·深度学习·学习·react.js·django·transformer
张彦峰ZYF6 小时前
高并发场景下的缓存雪崩探析与应对策略
redis·分布式·缓存
一 乐6 小时前
健身房预约|基于springboot + vue健身房预约小程序系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习·小程序