当前位置: 首页 > news >正文

RabbitMQ学习系列(五):routing路由模式和Topic主题模式

(一)routing路由模式

在前面一篇博客中讲到了exchange的类型,其中direct类型的exchange就是用于routing路由模式。direct类型的交换机是指:交换机和队列绑定时会设置路由键(routingkey),当消息从生产者发送给交换机时也会发送一个路由键。只有当这两个路由键相同时,交换机才会把消息发送给队列。

如上图所示,当生产者发送消息的路由键为error时,两个队列均可以收到消息;当生产者发送消息的路由键为info或warning时,只有第二个队列可收到消息。

(二)路由模式实践

2.1 工具类

工具类和之前都一样,不做介绍了

public class ConnectionUtil {
    public static Connection getConnection() throws IOException, TimeoutException {
        //定义一个连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        //设置服务地址
        factory.setHost("127.0.0.1");
        //设置AMQP端口
        factory.setPort(5672);
        //设置VHOSTS
        factory.setVirtualHost("/vhosts_sdxb");
        //设置用户名
        factory.setUsername("user_sdxb");
        factory.setPassword("123456");
        return factory.newConnection();
    }
}

2.2 生产者

与前面几种模式不同的地方已经通过注解标出,其中交换机类型选择成direct,并且按需要设置路由键

public class Sent {
    private static final String EXCHANGENAME="routing_exchange";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //交换机类型选择direct
        channel.exchangeDeclare(EXCHANGENAME,"direct");
        String msg="hello world";
        //设置路由键(routingkey)
        String routingkey="error";
        channel.basicPublish(EXCHANGENAME,routingkey,null,msg.getBytes());
        channel.close();
        connection.close();
    }
}

2.3 消费者一

在队列绑定时设置队列的路由键

public class Receive1 {
    private static final String QUEUENAME="routing_queue1";
    private static final String EXCHANGENAME="routing_exchange";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        final Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUENAME, false, false, false, null);
        //在队列绑定时设置路由键
        channel.queueBind(QUEUENAME, EXCHANGENAME, "error");
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("receive:" + msg);
            }
        };
        //监听队列
        channel.basicConsume(QUEUENAME, true, consumer);
    }
}

2.4 消费者二

在第二个消费者的队列中设置多个路由键

public class Receive2 {
    private static final String QUEUENAME="routing_queue2";
    private static final String EXCHANGENAME="routing_exchange";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        final Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUENAME, false, false, false, null);
        //在队列绑定时设置多个路由键
        channel.queueBind(QUEUENAME, EXCHANGENAME, "error");
        channel.queueBind(QUEUENAME, EXCHANGENAME, "info");
        channel.queueBind(QUEUENAME, EXCHANGENAME, "warning");
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("receive:" + msg);
            }
        };
        //监听队列
        channel.basicConsume(QUEUENAME, true, consumer);
    }
}

2.5运行结果

当路由键为error时,两个消费者均输出消息。当路由键为info或warning时,只有第二个消费者输出消息。

(三)Topic主题模式

Topic主题模式和routing路由模式类似,只不过这里的交换机使用的是topic类型,topic类型的交换机和direct的不同就在于topic可以匹配通配符。*代表匹配一个元素,#代表匹配一个或多个元素

以上图为例,Q1队列的路由键为*.orange.*,Q2队列的路由键为*.*.rabbitlazy.#,当消息的路由键为quick.orange.rabbit时,两个队列均能收到,当消息的路由键为lazy.orange.male.rabbit时,只有Q2队列能收到。

(四)主题模式实践

在routing路由模式的代码基础上修改

4.1 生产者

//交换机类型选择direct
channel.exchangeDeclare(EXCHANGENAME,"topic");
//设置路由键(routingkey)
String routingkey="lazy.brown.fox";

4.2 消费者一

channel.queueBind(QUEUENAME, EXCHANGENAME, "*.orange.*");

4.3 消费者二

channel.queueBind(QUEUENAME, EXCHANGENAME, "*.*.rabbit");
channel.queueBind(QUEUENAME, EXCHANGENAME, "lazy.#");

修改以上几处地方就实现了上述topic模型

相关文章:

  • RabbitMQ学习系列(六):RabbitMQ消息确认机制
  • cisco 交换机自动备份配置
  • 应届毕业生因为疫情休息在家,可以通过哪些途径提高自己?
  • APP产品交互设计分析总结(不断更新中...)
  • 以SpringBoot作为后台实践ajax异步刷新
  • 观察:阿里的VR实验室能解决什么问题?
  • JavaIO详解--JavaIO的整体结构以及File类的使用
  • 学习笔记:对象,原型和继承(1)
  • JavaIO详解--快速学懂字节流与字符流
  • 搭建IM服务 so easy
  • JavaIO详解--尽可能将BIO、NIO、AIO讲得通俗易懂
  • 用jedis获取redis连接(集群和非集群状态下)
  • Mysql的索引调优详解:如何去创建索引以及避免索引失效
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • 经验分享:JAVA实习生刚进公司主要做些什么?以及进入职场后我的心理变化
  • 2017-09-12 前端日报
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • Create React App 使用
  • gf框架之分页模块(五) - 自定义分页
  • Github访问慢解决办法
  • Median of Two Sorted Arrays
  • SpingCloudBus整合RabbitMQ
  • 盘点那些不知名却常用的 Git 操作
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 入门级的git使用指北
  • 三栏布局总结
  • 使用Gradle第一次构建Java程序
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • #LLM入门|Prompt#3.3_存储_Memory
  • (2024最新)CentOS 7上在线安装MySQL 5.7|喂饭级教程
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (二)springcloud实战之config配置中心
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (三分钟)速览传统边缘检测算子
  • (算法)N皇后问题
  • (五)MySQL的备份及恢复
  • (转)linux下的时间函数使用
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .net 获取url的方法
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .net流程开发平台的一些难点(1)
  • .net与java建立WebService再互相调用
  • .NET中使用Protobuffer 实现序列化和反序列化
  • ?.的用法
  • @Import注解详解
  • @NestedConfigurationProperty 注解用法
  • @Query中countQuery的介绍
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法