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都能接收到该条消息。

相关推荐
Stardep12 分钟前
算法2—八大常用排序算法(下)
c语言·数据结构·笔记·算法·排序算法·1024程序员节
FakeOccupational16 分钟前
【p2p、分布式,区块链笔记 IPFS】go-ipfs windows系统客户端节点实现 kubo试用
分布式·区块链·p2p
清酒伴风(面试准备中......)18 分钟前
开发流程初学者指南——项目管理
笔记·项目管理·开发流程
QQ_77813297426 分钟前
关于深度学习方向学习的一些建议
人工智能·深度学习·学习
哦哦~92144 分钟前
Fluent和深度学习算法驱动的流体力学计算与应用
人工智能·深度学习·学习·算法
霍格沃兹测试开发学社测试人社区1 小时前
软件测试学习笔记丨SeleniumPO模式
软件测试·笔记·测试开发·学习
问道飞鱼1 小时前
【分布式技术】分布式事务深入理解
分布式·saga·2pc·fmt·3pc
龙哥·三年风水1 小时前
群控系统服务端开发模式-应用开发-业务架构逻辑开发第一轮测试
分布式·php·群控系统
linly12191 小时前
R学习笔记-单因素重复测量方差分析
笔记·学习