首页 > 其他分享 >RabbitMQ系列学习笔记(十)--通配符模式

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

时间:2024-10-18 21:17:59浏览次数:8  
标签:String -- 绑定 通配符 RabbitMQ 队列 系列学习 queueName channel

文章目录

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

一、通配符模式原理

result.png
通配符模式(Topics)是在路由模式的基础上,给队列绑定带通配符的路由关键字,只要消息的 RoutingKey 能实现通配符匹配,就会将消息转发到该队列。通配符模式比路由模式更灵活,通配符模式使用** topic 交换机**。 能按照通配符规则将消息发送给指定队列。
发送到类型是 topic 交换机的消息的 routingkey 不能随意写,必须满足一定的要求,它必须是一个词列表,以点号分隔开。这些词可以是任意的。
比如说:“stock.usd.nyse”,“nyse.vmw”,“quick.orange.rabbit” 这种类型的。但这个词列表最多不能超过 255 个字节。
通配符规则如下:

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

二、通配符模式实战

result.png
上图绑定关系如下:

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

1、消费者代码

消费者01代码如下:

/**
 * 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代码如下:

/**
 * 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、生产者代码

/**
 * 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、查看运行结果

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

标签:String,--,绑定,通配符,RabbitMQ,队列,系列学习,queueName,channel
From: https://blog.csdn.net/m0_51621836/article/details/143062625

相关文章

  • 递推数列的极限(上)------单调有界部分
    不管怎么样,求极限之前都要先证明极限存在,即数列收敛。证明数列收敛两种方法:一种是单调有界准则,一种是夹逼准则。一.单调有界准则例1上面这道题的心路历程:先在草稿纸用上帝视角求出‘极限’,虽然是猜的,但是一定是对的。然后根据这个极限,以及题目给的条件,比如这道题给......
  • Java方法使用的细节
    在Java中,方法是一段可重用的逻辑代码块,用于执行特定的任务。以下是关于Java方法使用的一些细节:方法声明:方法应该先声明,再调用。方法的声明包括方法名、参数列表、返回类型和方法体。方法名应该以小写字母开头,并采用驼峰命名法。参数列表包括参数的类型和名称,多个参数之间用逗......
  • 八,Lambda表达式
    JavaLambda表达式与枚举Lambda表达式概述Java从JDK1.8开始引入了Lambda表达式,以简化代码开发并支持函数式编程。Lambda表达式可以避免面向对象编程中的一些繁琐问题,但同时也是一把双刃剑。Lambda表达式的使用场景必须有相应的函数接口,即内部有且仅有一个抽象方法的接口。......
  • 浅谈 tarjan
    就是记录两个数组:dfn[]和low[]其中dfn[]表示访问的顺序,low[u]用来存储\(u\)不经过其父亲能到达的最小时间戳。。。搬一下wiki的图。。。我们发现\(low[v]\gedfn[u]\)可以表示不能回到祖先,则\(u\)点位割点。。。直接上代码P3388------>#include<bits/stdc++.h>usi......
  • zyx是猫娘。每当她脾气暴躁的时候其实就是她发情了。还因为她的熙缺水补火导致整个人上火了。哦我的天哪,zyx怎么是这样的呢?但小编也很惊讶,接下来我们就来看看zyx为什么是猫娘吧。zyx是怎么变成的猫娘呢,其实是因为zyx是catgirl所以她就是猫娘。......
  • linux命令
    cd 进入目录cd/ 进入根目录cd.. 返回上一级cd../.. 返回上两级cd../../.. 返回上三级pwd 显示当前路径mkdir 创建目录mkdir-pa/b/c/d 创建层级目录ls 横向显示所有文件ll 纵向显示所有文件ll-a 显示隐藏文件ping 查看网络touch 创建文档vim 编辑文档cat 查......
  • cm
    CTH使我假完了!都怪CTH!!!后天再调#include<bits/stdc++.h>#defineintlonglong#defineme(a)memset(a,0,sizeofa)#definelsonls[rt]#definersonrs[rt]#defineAqrfre(x,y)freopen(#x".in","r",stdin),freopen(#y".out",......
  • ES数据聚合
    1.什么是数据聚合聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如:什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售情况如何?实现这些统计功能的比数据库的sql要方便的多,而且查询速度非常快,可以实现近实时......
  • 104. 建造最大岛屿(kamacoder)
    https://kamacoder.com/problempage.php?pid=1176importjava.util.*;publicclassMain{staticint[]dx={0,1,0,-1};staticint[]dy={1,0,-1,0};staticintn;staticintm;staticint[][]grid;staticboolean[][]vis;statici......
  • 怎么这么唐诗的 DS 都做不出来啊
    虽然下蛋爷和红黑树都没做出来。description你有一颗有根树,有三种操作:对\(x\)子树内深度为\(k\)的所有点\(+s\)并求出最大值。对\(x\)子树内深度\(\lek\)的所有点\(+s\)并求出最大值。对\(x\)子树内所有点\(+s\)并求出最大值。规定:子树内,子树的根节点深......