RabbitMQ的Topics主题模式

本文介绍了RabbitMQ的Topics主题模式,包括模式说明、代码实现、效果测试和小结。Topics模式允许队列在绑定Routing Key时使用通配符,如`#`匹配多个词,`*`匹配一个词。文中提供了生产者和两个消费者的代码示例,展示了如何利用通配符实现灵活的消息路由。测试结果显示,不同Routing Key的消息被正确路由到对应的队列。
摘要由CSDN通过智能技术生成

RabbitMQ的Topics主题模式

java_久孤是一名对技术持有独钟热爱的java资深程序员,崇尚程序界的开源精神,乐于做一个技术价值分享的博主,愿程序在你我这永远不迷茫

a.模式说明

在这里插入图片描述
Topic类型与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!

Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert

通配符规则:

#:匹配一个或多个词

*:匹配不多不少恰好1个词

举例:

item.#:能够匹配item.insert.abc 或者 item.insert

item.*:只能匹配item.insert
在这里插入图片描述
图解:

  • 红色Queue:绑定的是usa.# ,因此凡是以 usa.开头的routing key 都会被匹配到
  • 黄色Queue:绑定的是#.news ,因此凡是以 .news结尾的 routing key 都会被匹配

b.代码实现

1)生产者

使用topic类型的Exchange,发送消息的routing key有3种: item.insert、item.update、item.delete:

创建com.guigu.rabbitmq.topic.TopicProducer实现消息生产,代码如下:

public class TopicProducer {

    /***
     * 订阅模式-Topic
     * @param args
     */
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建链接对象
        Connection connection = ConnectionUtil.getConnection();

        //创建频道
        Channel channel = connection.createChannel();

        /**
         * 声明交换机
         * 参数1:交换机名称
         * 参数2:交换机类型,fanout、topic、direct、headers
         */
        channel.exchangeDeclare("topic_exchange", BuiltinExchangeType.TOPIC);

        /**
         * 声明队列
         * 参数1:队列名称
         * 参数2:是否定义持久化队列
         * 参数3:是否独占本次连接
         * 参数4:是否在不使用的时候自动删除队列
         * 参数5:队列其它参数
         */
        channel.queueDeclare("topic_queue_1",true,false,false,null);
        channel.queueDeclare("topic_queue_2",true,false,false,null);

        //队列绑定交换机,同时添加routekey过滤
        channel.queueBind("topic_queue_1","topic_exchange","item.update");
        channel.queueBind("topic_queue_1","topic_exchange","item.delete");
        channel.queueBind("topic_queue_2","topic_exchange","item.*");

        //消息-item.insert
        String message_insert = "发布订阅模式-Topic-item.insert:欢迎来到传深圳黑马训练营程序员中心!";
        /**
         * 消息发送
         * 参数1:交换机名称,如果没有指定则使用默认Default Exchage
         * 参数2:路由key,简单模式可以传递队列名称
         * 参数3:消息其它属性
         * 参数4:消息内容
         */
        channel.basicPublish("topic_exchange","item.insert",null,message_insert.getBytes());

        //消息-item.update
        String message_update = "发布订阅模式-Topic-item.update:欢迎来到传深圳黑马训练营程序员中心!";
        channel.basicPublish("topic_exchange","item.update",null,message_update.getBytes());

        //消息-item.delete
        String message_delete = "发布订阅模式-Topic-item.delete:欢迎来到传深圳黑马训练营程序员中心!";
        channel.basicPublish("topic_exchange","item.delete",null,message_delete.getBytes());

        //关闭资源
        channel.close();
        connection.close();
    }
}
2)消费者one

上面配置了路由绑定过滤的规则,如下图:在这里插入图片描述
创建com.guigu.rabbitmq.topic.ConsumerOne实现对topic_queue_1队列数据的消费,代码如下:

public class ConsumerOne {

    /***
     * 订阅模式消息消费者-Topic
     * @param args
     */
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建链接对象
        Connection connection = ConnectionUtil.getConnection();

        //创建频道
        Channel channel = connection.createChannel();

        /**
         * 声明队列
         * 参数1:队列名称
         * 参数2:是否定义持久化队列
         * 参数3:是否独占本次连接
         * 参数4:是否在不使用的时候自动删除队列
         * 参数5:队列其它参数
         */
        channel.queueDeclare("topic_queue_1",true,false,false,null);

        //创建消费者;并设置消息处理
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //路由key
                System.out.println("路由key为:" + envelope.getRoutingKey());
                //交换机
                System.out.println("交换机为:" + envelope.getExchange());
                //消息id
                System.out.println("消息id为:" + envelope.getDeliveryTag());
                //收到的消息
                System.out.println("消费者Topic-Queue-1-接收到的消息为:" + new String(body, "utf-8"));
            }
        };

        //消息监听
        channel.basicConsume("topic_queue_1",true,defaultConsumer);

        //关闭资源
        //channel.close();
        //connection.close();
    }
}
3)消费者Two

在这里插入图片描述
接收所有类型的消息:新增商品,更新商品和删除商品。

创建com.guigu.rabbitmq.topic.ConsumerTwo实现消息消费,代码如下:

public class ConsumerTwo {

    /***
     * 订阅模式消息消费者-Topic
     * @param args
     */
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建链接对象
        Connection connection = ConnectionUtil.getConnection();

        //创建频道
        Channel channel = connection.createChannel();

        /**
         * 声明队列
         * 参数1:队列名称
         * 参数2:是否定义持久化队列
         * 参数3:是否独占本次连接
         * 参数4:是否在不使用的时候自动删除队列
         * 参数5:队列其它参数
         */
        channel.queueDeclare("topic_queue_2",true,false,false,null);

        //创建消费者;并设置消息处理
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //路由key
                System.out.println("路由key为:" + envelope.getRoutingKey());
                //交换机
                System.out.println("交换机为:" + envelope.getExchange());
                //消息id
                System.out.println("消息id为:" + envelope.getDeliveryTag());
                //收到的消息
                System.out.println("消费者Topic-Queue-2-接收到的消息为:" + new String(body, "utf-8"));
            }
        };

        //消息监听
        channel.basicConsume("topic_queue_2",true,defaultConsumer);

        //关闭资源
        //channel.close();
        //connection.close();
    }
}

c.效果测试

启动所有消费者,然后使用生产者发送消息;在消费者对应的控制台可以查看到生产者发送对应routing key对应队列的消息;到达按照需要接收的效果;并且这些routing key可以使用通配符。
在这里插入图片描述
在这里插入图片描述
在执行完测试代码后,其实到RabbitMQ的管理后台找到Exchanges选项卡,点击 topic_exchange 的交换机,可以查看到如下的绑定:
在这里插入图片描述

d.小结

Topic主题模式可以实现 Publish/Subscribe发布与订阅模式 和 Routing路由模式 的功能;只是Topic在配置routing key 的时候可以使用通配符,显得更加灵活。

最后

无数个黑夜下的点滴创作,为的就是在这个行业领域下贡献一份属于自己的绵薄价值。小赞赞和关注走一波,关注博主不迷路,日后持续更新对你有帮助的实在干货

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值