RabbitMQ六种工作模式—主题模式

本文介绍了RabbitMQ的主题模式,其中routing_key必须遵循特定规则,如单词列表用点号分隔。主题模式中,*(星号)可替代一个单词,#(井号)可替代零个或多个单词。通过示例展示了不同队列如何根据绑定规则接收消息。

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

1.主题模式下

        发送到类型是 topic 交换机的消息的 routing_key 不能随意写,必须满足一定的要求,它必须是一个单词列表,以点号分隔开。这些单词可以是任意单词,比如:

        "stock.usd.nyse","nyse.vmw"

        "quick.orange.rabbit"等这些类型

        当然这个单词列表最多不能超过 255 个字节

        在这个规则列表中,其中有两个替换符是需要注意的,*(星号)可以代替一个单词,#(井号)可以替代零个或多个单词。

2.匹配案例

        Q1-->绑定的是 中间带 orange 带 3 个单词的字符串(*.orange.*)

        Q2-->绑定的是 最后一个单词是 rabbit 的 3 个单词(*.*.rabbit)或者第一个单词是 lazy 的多个单词(lazy.#)

        quick.orange.rabbit         被队列 Q1Q2 接收到

        lazy.orange.elephant      被队列 Q1Q2 接收到

        quick.orange.fox             被队列 Q1 接收到

        lazy.brown.fox                 被队列 Q2 接收到

        lazy.pink.rabbit                虽然满足两个绑定但只被队列 Q2 接收一次

        quick.brown.fox               不匹配任何绑定不会被任何队列接收到会被丢弃

        quick.orange.male.rabbit 是四个单词不匹配任何绑定会被丢弃

        lazy.orange.male.rabbit   是四个单词但匹配 Q2 

3.演示案例

生产者,匹配不同的routingKey

package org.example.Topic;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 生产者:发消息
 */
public class Producer {
    public static final String EXCHANGE_NAME="topic";

    public static void main(String[] args) throws Exception{
        // 创建一个连接工厂
        ConnectionFactory factory=new ConnectionFactory();
        // 工厂ip
        factory.setHost("112.124.16.34");
        factory.setUsername("admin");
        factory.setPassword("123456");
        factory.setPort(5672);
        // 创建连接
        Connection connection=factory.newConnection();
        // 获取信道
        Channel channel=connection.createChannel();

        Map<String,String> bindingKeyMap=new HashMap<>();
        bindingKeyMap.put("quick.orange.rabbit","被队列1和2接收到");
        bindingKeyMap.put("lazy.orange.elephant","被队列1和2接收到");
        bindingKeyMap.put("quick.orange.fox","被队列1接收到");
        bindingKeyMap.put("lazy.brown.fox","被队列2接收到");
        bindingKeyMap.put("lazy.pink.rabbit","虽然满足两个绑定但只被队列2接收一次");
        bindingKeyMap.put("quick.brown.fox","不匹配任何绑定不会被任何队列接收到,会被丢弃");
        bindingKeyMap.put("quick.orange.male.rabbit","是四个单词不匹配任何绑定,会被丢弃");
        bindingKeyMap.put("lazy.orange.male.rabbit","是四个单词但匹配队列2");
        /**
         * 发布消息
         * 1.exchange   发送到哪一个交换机,不填则选择默认交换机
         * 2.routingKey 路由对于默认交换机,路由键就是目标队列名称
         * 3.其它参数信息
         * 4.发送的消息
         */
        for(Map.Entry<String,String>bindingKeyEntry:bindingKeyMap.entrySet()){
            String routingKey=bindingKeyEntry.getKey();
            String message=bindingKeyEntry.getValue();
            channel.basicPublish(EXCHANGE_NAME,routingKey,null,message.getBytes("UTF-8"));
            System.out.println("生产者发出消息:"+message);
        }
        // 关闭通道和连接
        channel.close();
        // ***关闭连接***
        connection.close();
    }
}

队列1 

package org.example.Topic;

import com.rabbitmq.client.*;
/**
 * 消费者1
 */
public class Consumer01 {
    // 交换机的名称
    // 队列名称
    public static final String EXCHANGE_NAME="topic";
    public static final String QUEUE_NAME="queue_01";

    public static void main(String[] args) throws Exception{
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("112.124.16.34");
        factory.setUsername("admin");
        factory.setPassword("123456");
        factory.setPort(5672);
        Connection connection= factory.newConnection();
        Channel channel=connection.createChannel();
        // 声明交换机,交换机名称,类型
        // 声明队列
        // 主题交换机和队列绑定
        channel.exchangeDeclare(EXCHANGE_NAME,BuiltinExchangeType.TOPIC);
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"*.orange.*");
        /**
         * 消费者消费
         * 1.消费的队列
         * 2.消费成功之后是否自动应答
         * 3.deliverCallback
         * 4.cancelCallback
         */
        // 接收和处理消息的回调对象
        DeliverCallback deliverCallback=(consumerTag,message)->{
            String mes=new String(message.getBody(),"UTF-8");
            System.out.println("queue1—接收到消息:"+mes);
        };
        // 消费者取消时的回调对象
        CancelCallback cancelCallback=(consumerTag)->{
            System.out.println("消费被中断");
        };
        channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);

    }
}

队列2

package org.example.Topic;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * 消费者2
 */
public class Consumer02 {
    // 交换机的名称
    // 队列名称
    public static final String EXCHANGE_NAME="topic";
    public static final String QUEUE_NAME="queue_02";

    public static void main(String[] args) throws Exception{
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("112.124.16.34");
        factory.setUsername("admin");
        factory.setPassword("123456");
        Connection connection= factory.newConnection();
        Channel channel=connection.createChannel();
        // 声明交换机: 交换机名称,类型
        // 声明队列
        // 主题交换机和队列绑定
        channel.exchangeDeclare(EXCHANGE_NAME,BuiltinExchangeType.TOPIC);
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"*.*.rabbit");
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"lazy.#");
        /**
         * 消费者消费
         * 1.消费的队列
         * 2.消费成功之后是否自动应答
         * 3.deliverCallback
         * 4.cancelCallback
         */
        // 接收和处理消息的回调对象
        DeliverCallback deliverCallback=new DeliverCallback() {
            @Override
            public void handle(String consumerTag, Delivery message) throws IOException {
                String mes=new String(message.getBody(),"UTF-8");
                System.out.println("queue2—接收到消息:"+mes);
            }
        };
        // 消费者取消时的回调对象
        CancelCallback cancelCallback=new CancelCallback() {
            @Override
            public void handle(String consumerTag) throws IOException {
            }
        };
        channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);
        channel.close();
        // ***关闭连接***
        connection.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馒头爱学Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值