RabbitMQ系列--主题(Topic)

上一篇博客中,我们使用了direct类型的交换机,使得消费者有能力进行选择性的消息。但是仍然存在一些局限性:它不能够基于多重条件进行路由选择。 我们可以使用Topic类型的交换机解决这个问题。

Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key的时候可以使用通配符!这种模型的Routingkey一般都是由一共或多个单词组成,多个单词之间以"."分割,例如:item.insert;
在这里插入图片描述
通配符

  • #匹配0个或多个词
  • *匹配不多不少恰好1个词

比如上图中的 * .orange. * 与Q1队列进行了绑定,* .* . rabbit和lazy.#与Q2队列进行了绑定, 那么生产者发送路由key为user.orange.key会被消费者C1接收到。 发送路由key为user.orange.rabbit的消息,会被消费者C1和消费者C2都接收到。 如果发送lazy或lazy.aa或lazy.aa.aa 都会被消费者C2接收到。

接下来让我们用代码来验证下;

1.定义生产者

public class Provider {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();

        //将通道声明指定交换机
        //参数1:交换机名称   参数2:交换机的类型  direct 路由类型
        //没有交换机会创建一共名为logs的交换机
        channel.exchangeDeclare("topics","topic");

        //路由Key
        String routerKey = "user.orange.key";
        //发送消息
        channel.basicPublish("topics",routerKey,null,("这是基于topics的 [ "+ routerKey+"]的消息").getBytes());

        //关闭连接和通道
        RabbitMQUtils.closeChannelAndConnection(channel,connection);
    }
}

2.定义消费者1

public class Customer1 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        //通道绑定交换机
        channel.exchangeDeclare("topics","topic");

        //创建一个临时的、唯一的队列
        //返回的是 临时队列名
        String queueName = channel.queueDeclare().getQueue();

        //绑定交换机和队列
        //参数1: 队列名称  参数2:交换机名称  参数3:路由名称
        channel.queueBind(queueName,"topics","*.orange.*");
        //消费消息
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1:"+new String(body));
            }
        });
    }
}

3.定义消费者2

public class Customer2 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();

        //通道绑定交换机
        channel.exchangeDeclare("topics","topic");

        //创建一个临时的、唯一的队列
        //返回的是 临时队列名
        String queueName = channel.queueDeclare().getQueue();

        //绑定交换机和队列
        //参数1: 队列名称  参数2:交换机名称  参数3:路由名称
        channel.queueBind(queueName,"topics","*.*.rabbit");
        channel.queueBind(queueName,"topics","lazy.#");

        //消费消息
        channel.basicConsume(queueName,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2:"+new String(body));
            }
        });
    }
}

先运行消费者1和消费者2,在运行生产者。 可以发现只有消费者1接收到了消息
在这里插入图片描述
在这里插入图片描述

修改生产者的路由Key

 String routerKey = "user.orange.rabbit";

再次运行生产者,可以发现消费者1和消费者2都收到了消息
在这里插入图片描述
在这里插入图片描述

修改生产者路由key

 String routerKey = "lazy";

在这里插入图片描述
只有消费者2收到了消息。

可以看到,我们通过使用topic类型的交换机,成功实现了多重条件进行路由选择。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值