【RabbitMQ】Exchange实践

DirectExchange模式

只有当 Routing Key 等于 Binding Key 时,消息才会被路由到队列中。

搭建RabbitMq生产者

1、创建maven项目
2、引入相关依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
<!--使用阿里云仓库加快依赖包的下载速度-->
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

3、配置文件

server:
  port: 8001
spring:
  rabbitmq:
    addresses: 47.94.217.248
    port: 5672
    username: guest
    password: guest

4、创建RabbitMq配置
RabbitMq 的相关配置主要包括以下:

  • 定义Exchange类型、名称
  • 定义Queue 队列
  • 定义Binding 使exchange和queue通过routing-key绑定起来
@Configuration
public class RabbitMQConfig {
    // 定义短信队列
    public final static String SHORT_MESSAGE_QUEUE="SHORT_MESSAGE_QUEUE";
    @Bean
    public Queue shortMessageQueue(){
        return new Queue(RabbitMQConfig.SHORT_MESSAGE_QUEUE);
    }
    // 定义fanout短信交换机
    public final static String FANOUT_SHORT_MESSAGE_EXCHANGE="FANOUT_SHORT_MESSAGE_EXCHANGE";
    @Bean
    public FanoutExchange fanoutShortMessageExchange() {
        return new FanoutExchange(RabbitMQConfig.FANOUT_SHORT_MESSAGE_EXCHANGE);
    }
    // 定义direct交换机
    public final static String DIRECT_SHORT_MESSAGE_EXCHANGE="DIRECT_SHORT_MESSAGE_EXCHANGE";
    @Bean
    public DirectExchange directShortMessageExchange(){
        return new DirectExchange(RabbitMQConfig.DIRECT_SHORT_MESSAGE_EXCHANGE);
    }
    // 定义topic交换机
    public final static String TOPIC_SHORT_MESSAGE_EXCHANGE="TOPIC_SHORT_MESSAGE_EXCHANGE";
    @Bean
    public TopicExchange topicShortMessageExchange(){
        return new TopicExchange(RabbitMQConfig.TOPIC_SHORT_MESSAGE_EXCHANGE);
    }
    // 定义routing key
    public final static String SHORT_MESSAGE_ROUTING_KEY="SHORT_MESSAGE_ROUTING_KEY";
    /* 定义Binding,将DIRECT_SHORT_MESSAGE_EXCHANGE 交换机和 SHORT_MESSAGE_QUEUE 队列通过 SHORT_MESSAGE_ROUTING_KEY绑定到一起
     *   可以理解成,发送消息到'将DIRECT_SHORT_MESSAGE_EXCHANGE' 交换机时,'DIRECT_SHORT_MESSAGE_EXCHANGE' 这个交换机查找维护的路由表
     * (routing-key)找到相应的队列,然后再将消息推送到此队列
     */
    
    @Bean
    public Binding shortMessageBindingKey(){
        return BindingBuilder.bind(shortMessageQueue()).to(directShortMessageExchange()).with(RabbitMQConfig.SHORT_MESSAGE_ROUTING_KEY);
    }

    

}

5、发送消息

@RestController
@RequestMapping("/short-message")
@RequiredArgsConstructor
@Slf4j
public class ShortMessageController {
    private final RabbitTemplate rabbitTemplate;

    @GetMapping
    public void directExchangeProducer(){
       // 指定将消息发送给 ‘DIRECT_SHORT_MESSAGE_EXCHANGE’ 交换机,通过‘SHORT_MESSAGE_ROUTING_KEY’ 这个routing-key找到相应的队列 
       rabbitTemplate.convertAndSend(RabbitMQConfig.DIRECT_SHORT_MESSAGE_EXCHANGE,RabbitMQConfig.SHORT_MESSAGE_ROUTING_KEY,"directExchangeProducer:hello");
        log.info("directExchangeProducer send Message to "+RabbitMQConfig.SHORT_MESSAGE_ROUTING_KEY);
    }

}

搭建RabbitMq消费者

1、搭建maven项目
2、引入相关依赖(同producer)
3、配置文件 同producer ,需要更改下端口号
4、定义消费者

@Component
public class ShortMessageConsumer {
    private final static String SHORT_MESSAGE_QUEUE="SHORT_MESSAGE_QUEUE";
    private final static String DIRECT_SHORT_MESSAGE_EXCHANGE="DIRECT_SHORT_MESSAGE_EXCHANGE";
    public final static String SHORT_MESSAGE_ROUTING_KEY="SHORT_MESSAGE_ROUTING_KEY";
    // 消费者监听指定队列'SHORT_MESSAGE_QUEUE'
    @RabbitListener(queues = {SHORT_MESSAGE_QUEUE})
    public void listenShortMessage(String message){
        System.out.println("收到消息:"+message);
    }
}

测试结果

在这里插入图片描述

FanoutExchange模式

实现了一种广播机制,将消息发送到所有与这个 Exchange 绑定的队列中。
fanoutExchange 不需要设置routing-key。

1、 新建两个队列
在RabbitMqConfig文件中

    // 定义邮件队列
    public final static String EMAIL_MESSAGE_QUEUE="EMAIL_MESSAGE_QUEUE";
    @Bean
    public Queue emailMessageQueue(){
        return new Queue(RabbitMQConfig.EMAIL_MESSAGE_QUEUE);
    }
    // 定义邮件队列1
    public final static String EMAIL_MESSAGE_QUEUE_1="EMAIL_MESSAGE_QUEUE_1";
    @Bean
    public Queue emailMessageQueue1(){
        return new Queue(RabbitMQConfig.EMAIL_MESSAGE_QUEUE_1);
    }

2、 新建一个FanoutExchange

 // 定义fanout短信交换机
    public final static String FANOUT_SHORT_MESSAGE_EXCHANGE="FANOUT_SHORT_MESSAGE_EXCHANGE";
    @Bean
    public FanoutExchange fanoutShortMessageExchange() {
        return new FanoutExchange(RabbitMQConfig.FANOUT_SHORT_MESSAGE_EXCHANGE);
    }

3、新建两个binding
将fanoutExchange交换机和两个队列分别绑定

    @Bean
    public Binding fanoutBindingKey(){
        return BindingBuilder.bind(emailMessageQueue()).to(fanoutShortMessageExchange());
    }

    @Bean
    public Binding fanoutBindingKey1(){
        return BindingBuilder.bind(emailMessageQueue1()).to(fanoutShortMessageExchange());
    }

4、新建两个消费者
新建两个消费者,用来验证fanout交换机是否将消息广播给与他绑定的两个队列

    @RabbitListener(queues = {EMAIL_MESSAGE_QUEUE})
    public void fanoutShortMessage(String message){
        System.out.println("fanoutShortMessage收到消息:"+message);
    }
    @RabbitListener(queues = {EMAIL_MESSAGE_QUEUE_1})
    public void fanoutShortMessage1(String message){
        System.out.println("fanoutShortMessage1收到消息:"+message);
    }

5、发送消息与消费

// 注意,fanout交换机不需要指定rouing-key,所以routing-key 这个参数可以设置为null或者为空字符串(当我们将routing-key设置为null时,会使用的默认的routing-key 是个空字符串)

    @GetMapping("fanout")
    public void fanoutExchangeProducer(){
        rabbitTemplate.convertAndSend(RabbitMQConfig.FANOUT_SHORT_MESSAGE_EXCHANGE,null,"fanoutExchangeProducer:hello");
        log.info("fanoutExchangeProducer send Message");
    }

6、两个消费者都接收到消息
在这里插入图片描述

TopicExchange

定义了一种匹配规则,同样根据 Routing Key 和 Binding Key 进行模糊匹配,更加灵活

1、配置文件修改

// 定义队列
    public final static String TOPIC_QUEUE_1="TOPIC_QUEUE_1";
    public final static String TOPIC_QUEUE_2="TOPIC_QUEUE_2";
    public final static String TOPIC_QUEUE_3="TOPIC_QUEUE_3";
    @Bean
    public Queue topicQueue1(){
        return new Queue(TOPIC_QUEUE_1);
    }
    @Bean
    public Queue topicQueue2(){
        return new Queue(TOPIC_QUEUE_2);
    }
    @Bean
    public Queue topicQueue3(){
        return new Queue(TOPIC_QUEUE_3);
    }
    // 定义topic交换机
    public final static String TOPIC_SHORT_MESSAGE_EXCHANGE="TOPIC_SHORT_MESSAGE_EXCHANGE";
    @Bean
    public TopicExchange topicShortMessageExchange(){
        return new TopicExchange(RabbitMQConfig.TOPIC_SHORT_MESSAGE_EXCHANGE);
    }
    // 定义routing-key
    public final static String topic_routing_key_one="com.cxm.*";// 匹配com.cxm下所有(不包括com.cxm)
    public final static String topic_routing_key_two="com.ww.*";// 匹配com.ww下所有(不包括com.ww)
    public final static String topic_routing_key_three="com.cxm.#";// 匹配com.cxm下0个或多个(包括com.cxm)
    @Bean
    public Binding topicBindingOne(){
        return BindingBuilder.bind(topicQueue1()).to(topicShortMessageExchange()).with(topic_routing_key_one);
    }
    @Bean
    public Binding topicBindingTwo(){
        return BindingBuilder.bind(topicQueue2()).to(topicShortMessageExchange()).with(topic_routing_key_two);
    }
    @Bean
    public Binding topicBindingThree(){
        return BindingBuilder.bind(topicQueue3()).to(topicShortMessageExchange()).with(topic_routing_key_three);
    }

2、创建消费者

    public final static String TOPIC_QUEUE_1="TOPIC_QUEUE_1";
    public final static String TOPIC_QUEUE_2="TOPIC_QUEUE_2";
    public final static String TOPIC_QUEUE_3="TOPIC_QUEUE_3";
    @RabbitListener(queues = {TOPIC_QUEUE_1})
    public void topicShortMessage1(String message){
        System.out.println("TOPIC_QUEUE_1 收到消息:"+message);
    }
    @RabbitListener(queues = {TOPIC_QUEUE_2})
    public void topicShortMessage2(String message){
        System.out.println("TOPIC_QUEUE_2 收到消息:"+message);
    }
    @RabbitListener(queues = {TOPIC_QUEUE_3})
    public void topicShortMessage3(String message){
        System.out.println("TOPIC_QUEUE_3 收到消息:"+message);
    }

3、发送消息

  @GetMapping("topic")
    public void topicExchangeProducer(){
        rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_SHORT_MESSAGE_EXCHANGE,"com.cxm.abc","topicExchangeProducer:hello ,routing-key: com.cxm.abc");
        rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_SHORT_MESSAGE_EXCHANGE,"com.ww.5257","topicExchangeProducer:hello ,routing-key: com.ww.5257");
        rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_SHORT_MESSAGE_EXCHANGE,"com.cxm","topicExchangeProducer:hello ,routing-key: com.cxm");

    }

4、消费者接受到消息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hfg0QSm7-1650268573167)(evernotecid://3FF987EF-EC0D-4AE0-B527-B88DFA6E477C/appyinxiangcom/26972899/ENResource/p290)]

通过结果可以看出,只有com.cxm.#匹配到了com.cxm,因为#代表匹配0个或者多个!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

LLLDa_&

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

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

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

打赏作者

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

抵扣说明:

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

余额充值