RabbitMQ(三)------routing 路由选择/通配符模式

本文深入探讨了RabbitMQ的直接路由模式(direct),解释了如何通过不同的路由键将消息发送到相应的队列,以及如何配置多个消费者来处理不同类型的事件。通过具体的Java代码示例,展示了如何设置交换机、绑定队列,并实现消息的发布和消费。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Excahnge(交换机/转发器):

​ 一方面接收生产者的消息,另一方面是向队列推送消息

2.匿名转发 : “”;

3.fanout(不处理路由键)
在这里插入图片描述
direct(处理路由键)
在这里插入图片描述
路由模式:在这里插入图片描述
4.Send.java

public class Send {
    private static final String EXCHANGE_NAME = "test_exchange_direct";
    public static void main(String[] args) throws Exception{
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();

        //声明交换机
        channel.exchangeDeclare(EXCHANGE_NAME,"direct");

        String msg = "hello direct";
        String routingKey = "warning";
        channel.basicPublish(EXCHANGE_NAME,routingKey,null,msg.getBytes());

        System.out.println("send:"+msg);

        channel.close();
        connection.close();
    }
}

Receive1.java

public class Receive1 {
    private static final String EXCHANGE_NAME = "test_exchange_direct";
    private static final String QUEUE_NAME = "test_queue_direct_1";
    private static int i = 1;
    public static void main(String[] args) throws Exception{
        Connection connection = ConnectionUtils.getConnection();
        final Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME,false,false,false,null);

        channel.basicQos(1);

        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"error");

        //创建消费者
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            //一旦有消息就会触发这个方法
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String str = new String(body,"utf-8");
                System.out.println("[1] receive :"+str+"   "+(i++));
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("[1] done ");
                    //手动回执
                    channel.basicAck(envelope.getDeliveryTag(),false);
                }
            }
        };

        //监听队列  不让其自动应答
        channel.basicConsume(QUEUE_NAME,false,defaultConsumer);
    }
}

Receive2.java

public class Receive2 {
    private static final String EXCHANGE_NAME = "test_exchange_direct";
    private static final String QUEUE_NAME = "test_queue_direct_2";
    private static int i = 1;
    public static void main(String[] args) throws Exception{
        Connection connection = ConnectionUtils.getConnection();
        final Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME,false,false,false,null);

        channel.basicQos(1);

        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"error");
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"info");
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"warning");

        //创建消费者
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            //一旦有消息就会触发这个方法
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String str = new String(body,"utf-8");
                System.out.println("[2] receive :"+str+"   "+(i++));
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("[2] done ");
                    //手动回执
                    channel.basicAck(envelope.getDeliveryTag(),false);
                }
            }
        };

        //监听队列  不让其自动应答
        channel.basicConsume(QUEUE_NAME,false,defaultConsumer);
    }
}
### RabbitMQ 中 Topic 模式的使用与配置 #### 1. 基本概念 在 RabbitMQ 的 Topic 模式下,消息路由键(routing key)和绑定键(binding key)都可以包含多个单词,这些单词之间用点号 `.` 分隔。生产者发送消息时指定一个路由键,而消费者则通过定义特定的绑定键来订阅感兴趣的消息类型。 #### 2. 生产者的实现方式 对于生产者而言,在发送消息到 Topic 类型的交换机时,只需要调用 `convertAndSend` 方法并传入相应的参数即可。例如: ```java @Autowired private RabbitTemplate rabbitTemplate; public void sendMsg() { String exchangeName = "topicExchange"; String routingKey = "key1"; // 路由键应遵循一定的命名规则以便于匹配 Object messageBody = "This is a test message."; rabbitTemplate.convertAndSend(exchangeName, routingKey, messageBody); } ``` 此段代码展示了如何利用 Spring AMQP 提供的 `RabbitTemplate` 来向名为 `"topicExchange"` 的 Topic Exchange 发送一条带有自定义路由键的消息[^2]。 #### 3. 绑定关系设置 为了使消费者能够接收到符合条件的消息,需建立合适的绑定关系。这通常是在声明队列之后完成的操作,即先创建好队列再将其与某个 Topic Exchange 关联起来,并指明具体的 binding key 形式。比如下面的例子说明了一个简单的绑定过程: ```java // 定义队列名称以及对应的 Binding Key 表达式 String queueName = "testQueue"; String pattern = "*.orange.*"; // 执行绑定操作 amqpAdmin.declareBinding(BindingBuilder.bind(new Queue(queueName)) .to(new DirectExchange("topicExchange")) .with(pattern)); ``` 这里使用的 `pattern` 参数支持通配符语法,其中星号(*)代表任意单个词,井号(#)表示零个或多个词语[^4]。 #### 4. 实际应用场景中的注意事项 当实际应用中涉及到复杂的业务逻辑时,建议合理规划路由键的设计原则,确保其既具有足够的表达力又不会过于复杂难以维护;同时也要注意性能方面的影响因素,如过多的队列可能会导致资源消耗增加等问题[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值