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 分钟前
XLSR-Wav2Vec2:用于语音识别的无监督跨语言表示学习
人工智能·学习·语音识别
Cachel wood9 天前
Spark教程6:Spark 底层执行原理详解
大数据·数据库·分布式·计算机网络·spark
大熊猫侯佩9 天前
ruby、Python 以及 Swift 语言关于 “Finally” 实现的趣谈
python·ruby·swift
懒惰的bit9 天前
STM32F103C8T6 学习笔记摘要(四)
笔记·stm32·学习
zkyqss9 天前
OVS Faucet练习(下)
linux·笔记·openstack
Jay_5159 天前
C++ STL 模板详解:由浅入深掌握标准模板库
c++·学习·stl
冰茶_9 天前
ASP.NET Core API文档与测试实战指南
后端·学习·http·ui·c#·asp.net
丶Darling.9 天前
深度学习与神经网络 | 邱锡鹏 | 第五章学习笔记 卷积神经网络
深度学习·神经网络·学习
浦东新村轱天乐9 天前
【麻省理工】《how to speaking》笔记
笔记
奔跑的蜗牛AZ9 天前
TiDB 字符串行转列与 JSON 数据查询优化知识笔记
笔记·json·tidb