RabbitMQ(五)Routing 路由

1.概述

1.1 消费者绑定

在前面的示例中,我们已经在创建绑定。您可能会想起以下代码:

channel.queueBind(queueName,EXCHANGE_NAME,"");

绑定是交换和队列之间的关系。可以简单地理解为:队列对来自此交换的消息感兴趣。
绑定可以使用额外的routingKey参数。为了避免与basic_publish参数混淆,我们将其称为绑定键。这是我们如何使用键创建绑定的方法:

channel.queueBind(queueName,EXCHANGE_NAME,"key1");

1.2 直接交换 - direct

直接交换背后的路由算法很简单-一条消息进入其绑定密钥与该消息的路由密钥完全匹配的队列 。

为了说明这一点,请考虑以下设置:

在此设置中,我们可以看到绑定了两个队列的直接交换X。第一个队列由绑定键orange绑定,第二个队列有两个绑定,一个绑定键为black,另一个绑定为green。

在这样的设置中,使用路由键orange发布到交换机的消息 将被路由到队列Q1。路由键为black  或green 的消息将转到Q2。所有其他消息将被丢弃。

1.3 多重绑定

用相同的绑定密钥绑定多个队列是完全合法的。在我们的示例中,我们可以使用绑定键black在X和Q1之间,X和Q2之间添加绑定。在这种情况下,直接交换的行为将类似于扇出,并将消息广播到所有匹配的队列。带有黑色路由键的消息将同时传递到 Q1和Q2

2.代码示例

2.1 发送者

public class RouteSender {
    private  final static String EXCHANGE_NAME = "testRoute";//交换机名称

    public static void main(String[] args) throws Exception {
        //1.获取连接
        Connection connection = ConnectionUtil.getConnection();
        //2.创建通道
        Channel channel = connection.createChannel();
        //3.1 声名交换机
        //参数1,交换机名称
        //参数2,交换机类型,默认 direct(直接)
        channel.exchangeDeclare(EXCHANGE_NAME,"direct");
        //4.发送消息
        String msg = "发送路由消息";
        channel.basicPublish(EXCHANGE_NAME,"key3",null,msg.getBytes());
        //5.关闭连接
        channel.close();
        connection.close();
    }

2.2 消费者1

public class RouteRecv1 {
    private  final static String EXCHANGE_NAME = "testRoute";//交换机名称
    private  final static String QUEUE1 = "testQueue1";//临时队列名称

    public static void main(String[] args) throws Exception {
        //1.获取连接
        Connection connection = ConnectionUtil.getConnection();
        //2.创建通道
        Channel channel = connection.createChannel();
        //3.1 临时队列
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        String queueName = channel.queueDeclare().getQueue();
        //3.2 绑定队列到交换机
        //queue
        //exchange
        //routingKey 绑定键,绑定到交互及的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
        channel.queueBind(queueName,EXCHANGE_NAME,"key1");
        //如果要接收多个标记,只需要再执行一次即可
        channel.queueBind(queueName,EXCHANGE_NAME,"key2");
        //4.公平派遣:通知服务器,在消费确认前,不接收新发送的消息
        channel.basicQos(1);
        //5.定义消费者
        DefaultConsumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
               //打印收到的消息
                System.out.println("消费者11收到内容:"+new String(body));
                //7.消费者消息确认:参数2,false 为手动确认收到消息。
                //这里可以在异常捕获的时候,将它设置为true
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        //6.注册消费者,参数2,false代表我们收到消息后需要手动告诉服务器
        channel.basicConsume(queueName,false,consumer);

    }
}

2.3 消费者2

public class RouteRecv2 {
    private  final static String EXCHANGE_NAME = "testRoute";//交换机名称
    private  final static String QUEUE1 = "testQueue1";//临时队列名称

    public static void main(String[] args) throws Exception {
        //1.获取连接
        Connection connection = ConnectionUtil.getConnection();
        //2.创建通道
        Channel channel = connection.createChannel();
        //3.1 临时队列
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        String queueName = channel.queueDeclare().getQueue();
        //3.2 绑定队列到交换机
        //queue
        //exchange
        //routingKey 绑定键,绑定到交互及的时候会指定一个标记,只有和它一样的标记的消息才会被当前消费者接收到
        channel.queueBind(queueName,EXCHANGE_NAME,"key1");
        //如果要接收多个标记,只需要再执行一次即可
        channel.queueBind(queueName,EXCHANGE_NAME,"key3");
        //4.公平派遣:通知服务器,在消费确认前,不接收新发送的消息
        channel.basicQos(1);
        //5.定义消费者
        DefaultConsumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
               //打印收到的消息
                System.out.println("消费者22收到内容:"+new String(body));
                //7.消费者消息确认:参数2,false 为手动确认收到消息。
                //这里可以在异常捕获的时候,将它设置为true
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        //6.注册消费者,参数2,false代表我们收到消息后需要手动告诉服务器
        channel.basicConsume(queueName,false,consumer);

    }
}
RouteSender.java中,当参数routingKey为key1,key2,key3时,查看不通的接收结果。
channel.basicPublish(EXCHANGE_NAME,"key3",null,msg.getBytes());

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值