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

打印 上一主题 下一主题

主题 1044|帖子 1044|积分 3132

本文参考:
尚硅谷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代码如下:
  1. /**
  2. * Description: 通配符模式消费者01
  3. */
  4. public class ReceiveLogsTopic01 {
  5.    
  6.         private static final String EXCHANGE_NAME = "topic_logs";
  7.    
  8.     public static void main(String[] argv) throws Exception {
  9.                 Channel channel = RabbitUtils.getChannel();
  10.         channel.exchangeDeclare(EXCHANGE_NAME, "topic");
  11.                 //声明 Q1 队列与绑定关系
  12.         String queueName="Q1";
  13.                 channel.queueDeclare(queueName, false, false, false, null);
  14.         //绑定关系并指定routingkey
  15.         channel.queueBind(queueName, EXCHANGE_NAME, "*.orange.*");
  16.                 System.out.println("等待接收消息.....");
  17.             //接收消息
  18.         channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
  19.             @Override
  20.             public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
  21.                 String message = new String(body, "UTF-8");
  22.                 System.out.println("接收队列:" + queueName + "绑定键:" + envelope.getRoutingKey() + ",消息:" + message);
  23.             }
  24.         });
  25.     }
  26. }
复制代码
消耗者02代码如下:
  1. /**
  2. * Description: 通配符模式消费者02
  3. */
  4. public class ReceiveLogsTopic02 {
  5.    
  6.         private static final String EXCHANGE_NAME = "topic_logs";
  7.    
  8.     public static void main(String[] argv) throws Exception {
  9.                 Channel channel = RabbitUtils.getChannel();
  10.         channel.exchangeDeclare(EXCHANGE_NAME, "topic");
  11.                 //声明 Q2 队列与绑定关系
  12.         String queueName="Q2";
  13.                 channel.queueDeclare(queueName, false, false, false, null);
  14.         //绑定关系并指定routingkey
  15.         channel.queueBind(queueName, EXCHANGE_NAME, "*.*.rabbit");
  16.         channel.queueBind(queueName, EXCHANGE_NAME, "lazy.#");
  17.                 System.out.println("等待接收消息.....");
  18.             //接收消息
  19.         channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
  20.             @Override
  21.             public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
  22.                 String message = new String(body, "UTF-8");
  23.                 System.out.println("接收队列:" + queueName + "绑定键:" + envelope.getRoutingKey() + ",消息:" + message);
  24.             }
  25.         });
  26.     }
  27. }
复制代码
2、生产者代码

  1. /**
  2. * Description: 通配符模式消费者02
  3. */
  4. public class EmitLogTopic {
  5.         private static final String EXCHANGE_NAME = "topic_logs";
  6.     public static void main(String[] argv) throws Exception {
  7.         Channel channel = RabbitUtils.getChannel();
  8.                 Map<String, String> bindingKeyMap = new HashMap<>();
  9.         bindingKeyMap.put("quick.orange.rabbit","被队列 Q1Q2 接收到");
  10.         bindingKeyMap.put("lazy.orange.elephant","被队列 Q1Q2 接收到");
  11.                 bindingKeyMap.put("quick.orange.fox","被队列 Q1 接收到");
  12.         bindingKeyMap.put("lazy.brown.fox","被队列 Q2 接收到");
  13.                 bindingKeyMap.put("lazy.pink.rabbit","虽然满足两个绑定但只被队列 Q2 接收一次");
  14.                 bindingKeyMap.put("quick.brown.fox","不匹配任何绑定不会被任何队列接收到会被丢弃");
  15.                 bindingKeyMap.put("quick.orange.male.rabbit","是四个单词不匹配任何绑定会被丢弃");
  16.                 bindingKeyMap.put("lazy.orange.male.rabbit","是四个单词但匹配 Q2");
  17.                 for (Map.Entry<String, String> bindingKeyEntry: bindingKeyMap.entrySet()){
  18.             String routingKey = bindingKeyEntry.getKey();
  19.                         String message = bindingKeyEntry.getValue();
  20.             channel.basicPublish(EXCHANGE_NAME,routingKey, null, message.getBytes("UTF-8"));
  21.                         System.out.println("生产者发出消息" + message);
  22.                 }
  23.         }
  24. }
复制代码
3、查察运行结果

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



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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我可以不吃啊

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表