1. 概述

上篇文章中间件系列五 RabbitMQ之Direct exchange(直连交换机)和路由,我们通过direct exchange(直连交换机)可以根据路由键进行路由,但是还是不够灵活,它只能进行完全匹配。这节我们引入Topic exchange(主题交换机),支持对路由键的模糊匹配
上篇文章实现生产者发送一个消息,这个消息同时被传送给所有队列。但是有时我们不希望所有的消息都被所有队列接收,我们希望可以指定类型为a的消息只能被队列A接收,类型为b的消息只能被队列B,C接收。扇型交换机只能无脑地广播消息给所有的消费者,实质是广播给所有关联的队列。
为了实现这个功能,一种是建立多个交换机,这种方式简单暴力但是不灵活。本节我们介绍使用单个直连交换机+路由实现以上功能

2. 本文实现功能说明

上图中有3个绑定

队列Q1绑定键值"*.orange.*"
队列Q2绑定键值"*.*.rabbit", "lazy.#"

案例说明

1. 路由键"quick.orange.rabbit"和"lazy.orange.elephant"会被同时投递到Q1和Q2
2. 路由键"quick.orange.fox" 只被同时投递到Q1
3. 路由键"lazy.brown.fox" 只被投递到Q2
4. 路由键"lazy.pink.rabbit" 只会被投递到Q2,且只投递一次,尽管它同时符合两个键的值"*.*.rabbit", lazy.#"。
5. 路由键"quick.brown.fox"、"orange" 、 "quick.orange.male.rabbit" 没有符合两个队列的要求,被丢弃

路由键中特殊匹配字符说明

  • *(星号)可以代替一个字。
  • #(散列)可以代替零个或多个单词。

Topic Exchange的路由键条件:

  1. 必须是由英文单词列表组成,单词之间使用”.”分隔
  2. 路由键的长度最大255字节

3. 生产者代码

主要业务逻辑如下:

1. 配置连接工厂
2. 建立TCP连接
3. 在TCP连接的基础上创建通道
4. 声明一个topic交换机
5. 发送消息,并配置消息的路由键

此代码和上一篇的代码基本相同,最大的不同是声明了topic交换机

// 声明一个topic交换机
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);

完整代码
发送者代码: TopicsSend.java

4. 接收者代码

主要业务逻辑如下:

1. 配置连接工厂
2. 建立TCP连接
3. 在TCP连接的基础上创建通道
4. 声明一个topic交换机
5. 声明一个临时队列
6. 将临时队列绑定到交换机上,并在队列上绑定多个绑定值
7. 接收消息并处理

此代码和上一篇的代码基本相同,最大的不同是声明了topic交换机

// 声明一个topic交换机
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);

完整代码
消费者代码:TopicsRecv.java

5. 测试

BasicTest

@Test
public void topics() throws InterruptedException {// 消费者1:绑定 *.orange.* 值executorService.submit(() -> {String[] bindingKeys = {"*.orange.*"};TopicsRecv.execute(rabbitmq_host, rabbitmq_user, rabbitmq_pwd, bindingKeys);});// 消费者2:绑定  "*.*.rabbit" 和 "lazy.#"值executorService.submit(() -> {String[] bindingKeys = {"*.*.rabbit", "lazy.#"};TopicsRecv.execute(rabbitmq_host, rabbitmq_user, rabbitmq_pwd, bindingKeys);});Thread.sleep(5* 100);// 生产者1 : 发送 black,所有的接收端都会收到executorService.submit(() -> {String routing = "quick.orange.rabbit";TopicsSend.execute(rabbitmq_host, rabbitmq_user, rabbitmq_pwd, routing);});// 生产者2 : 发送 green,所有的接收端都不会收到executorService.submit(() -> {String routing = "lazy.pink.rabbit";TopicsSend.execute(rabbitmq_host, rabbitmq_user, rabbitmq_pwd, routing);});// sleep 10sThread.sleep(10 * 1000);
}

以上代码启动2个消费者,消费者1绑定”*.orange.*” ,消费者2个绑定”*.*.rabbit” 和 “lazy.#”;
启动2个生产者,生产者1发送消息的路由键为 “quick.orange.rabbit”,此消息同时被2个消费者接收
生产者2发送消息的路由键为”lazy.pink.rabbit”,此消息只被消费者2接收,符合之前的分析

// 启动2个消费者,消费者1绑定"*.orange.*" ,消费者2个绑定"*.*.rabbit" 和 "lazy.#"
[TopicsRecv [*.orange.*]] Waiting for messages.
[TopicsRecv [*.*.rabbit, lazy.#]] Waiting for messages.
// 生产者1发送消息的路由键为 "quick.orange.rabbit",此消息同时被2个消费者接收
[TopicsSend] Sent 'quick.orange.rabbit':'Topics-1516008766983'
[TopicsRecv [*.*.rabbit, lazy.#] ] Received 'quick.orange.rabbit':'Topics-1516008766983'
[TopicsRecv [*.orange.*] ] Received 'quick.orange.rabbit':'Topics-1516008766983'
// 生产者2发送消息的路由键为"lazy.pink.rabbit",此消息只被消费者2接收
[TopicsSend] Sent 'lazy.pink.rabbit':'Topics-1516008767012'
[TopicsRecv [*.*.rabbit, lazy.#] ] Received 'lazy.pink.rabbit':'Topics-1516008767012'

6. 代码

上文的详细代码主要如下:
发送者代码: TopicsSend.java
消费者代码:TopicsRecv.java
测试代码:BasicTest.java的方法 topics()
所有的详细代码见github代码,请尽量使用tag v0.10,不要使用master,因为master一直在变,不能保证文章中代码和github上的代码一直相同

中间件系列六 RabbitMQ之Topic exchange 用法相关推荐

  1. RabbitMq系列(九):主题交换Topic Exchange

    系列文章 RabbitMq系列(一):服务器搭建 RabbitMq系列(二):最简单的例子 RabbitMq系列(三):工作队列 RabbitMq系列(四):消息确认和持久性 RabbitMq系列(五 ...

  2. RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    一.Direct Exchange 任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue. 1.一般情况可以使用rabbitMQ自带的Exchange:&quo ...

  3. RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较(转)

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  4. springboot rabbitmq direct exchange和topic exchange 写法上关于路由键的区别

    这是direct exchange写法中消息发送写法,可见下图红色框中路由键是queue队列中定义的路由键 这是topic exchange写法中消息发送写法,可见下图红色框中路由键是exchange ...

  5. RabbitMQ Topic exchange

    Topic exchange topic与之前的每个类型都不同(ps:废话每个都是不同的).Topic解决了我们另一个需求.举个例子,有一个做资讯的公司,他们会收集各种科技公司的动态并且第一时间转发出 ...

  6. RabbitMQ 四种Exchange

    AMQP协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列.生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机.先由Exchange来接收,然后Exchang ...

  7. [系统安全] 四十四.APT系列(9)Metasploit技术之基础用法万字详解及防御机理

    您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列.因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全.逆向分 ...

  8. kafka创建topic_ELK-基础系列(六)-ELK加入消息队列-Kafka部署

    Kafka集群部署指南 一.前言 1.Kafka简介 Kafka是一个开源的分布式消息引擎/消息中间件,同时Kafka也是一个流处理平台.Kakfa支持以发布/订阅的方式在应用间传递消息,同时并基于消 ...

  9. RabbitMQ - 4种Exchange类型

    在rabbitmq中,exchange有4个类型:direct,topic,fanout,header. direct exchange 此类型的exchange路由规则很简单: exchange在和 ...

  10. Exchange server 2010系列教程之九 配置exchange server 2010 OWA(3)

    Exchange server 2010系列教程之九 配置exchange server 2010 OWA(3) 前面俩节说了owa的登录和webmail的简化,以及SSO的实现.下面大家看看这个网站 ...

最新文章

  1. 微服务架构下的静态数据通用缓存机制!
  2. C++多态的实现原理
  3. linux 逆向工具 radare2入门
  4. 网站制作之按钮onclick大全
  5. android 设备名称_如何更改您的Android TV的设备名称
  6. 数据结构——基于字符串模式匹配算法的病毒感染检测
  7. iOS多视图代码操作
  8. MyFlash——美团点评的开源MySQL闪回工具
  9. linux tar 备份命令
  10. 如何清除 MacBook 上的浏览​​器缓存
  11. 使用 aspose 框架实现ex转pdf,图片。word转pdf,图片。pdf转图片
  12. springboot的错误页面配置
  13. endnote 参考文献加序号_两招搞定参考文献自动编号与格式编排
  14. HTML学生个人网站作业设计:电影网站设计——橙色国外电影(13页) HTML+CSS+JavaScript 简单DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载
  15. mac 安装软件报错
  16. 【U3D小游戏】愤怒的小鸟(三)猪的相关
  17. Maltrail恶意流量检测系统
  18. 计算机丢失GetU,u盘启动引导文件丢失如何修复
  19. 1112day10:考前复习50题:断言
  20. 不要成为反DDoS攻击的局外人

热门文章

  1. 达梦数据库DSC小记
  2. Fastdb安装与使用
  3. Wireshark、Sniffer 两款网络分析工具的比较
  4. 关于CalendarUtil获取时间的工具类
  5. excel自动求和_Excel教程:3个按条件定位的小技巧
  6. 三角形的内切圆和外接圆半径公式
  7. APP测试工具-Doraemonkit使用
  8. VMware16虚拟机:安装Windows10系统---超详细教程
  9. 人脸识别翼闸使用规范_介绍市场上最常用的通道翼门和人脸识别的使用
  10. 计算机键盘没有fn,教您fn键设置方法