MQ-使用SpringAMQP实现发布订阅模型之Fanout Exchange

  Fanout Exchange:广播在这里插入图片描述

一、广播模式

  Fanout,英文翻译是扇出,在MQ中叫广播更合适。

在这里插入图片描述
  在广播模式下,消息发送流程是这样的:

  • 1) 可以有多个队列
  • 2) 每个队列都要绑定到Exchange(交换机)
  • 3) 生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定
  • 4) 交换机把消息发送给绑定过的所有队列
  • 5) 订阅队列的消费者都能拿到消息

  这里留下一个疑问,如果是两个消费者绑定同一个队列呢?那么这两个消费者是都可以拿到消息呢还是只有一各消费者可以拿到消息?

二、模拟计划

  创建一个交换机 gentlebrother.fanout,类型是
  创建两个队列 fanout.queue1 和 fanout.queue2,绑定到交换机 gentlebrother.fanout
  将消费者1和消费者2绑定到 queue1,将消费者3绑定到 queue2
在这里插入图片描述

三、模拟Fanout

1.声明队列和交换机

  Spring提供了一个接口Exchange,来表示所有不同类型的交换机:

在这里插入图片描述

  在 consumer 中创建一个 FanoutConfig 配置类,声明队列和交换机:

package cn.itcast.mq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 温柔哥
 * @create 2024-02-02 10:25
 */
@Configuration
public class FanoutConfig {

    /**
     * 声明交换机
     * @return Fanout 类型的交换机
     */
    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("gentlebrother.fanout");
    }

    /**
     * 声明第 1 个队列
     * @return
     */
    @Bean
    public Queue fanoutQueue1() {
        return new Queue("fanout.queue1");
    }


    /**
     * 将第 1 个队列绑定到交换机上
     * @param fanoutQueue1
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding fanoutBindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange) { // 类型和名称千万不要错了,要和上面定义的一样
        return BindingBuilder
                .bind(fanoutQueue1)
                .to(fanoutExchange);
    }

    /**
     * 声明第 2 个队列
     * @return
     */
    @Bean
    public Queue fanoutQueue2() {
        return new Queue("fanout.queue2");
    }


    /**
     * 将第 2 个队列绑定到交换机上
     * @param fanoutQueue2
     * @param fanoutExchange
     * @return
     */
    @Bean
    public Binding fanoutBindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange) {
        return BindingBuilder
                .bind(fanoutQueue2)
                .to(fanoutExchange);
    }
}

  运行 consumer 服务,去 mq 客户端查看是否声明和绑定成功

在这里插入图片描述

2.添加消费者监听消息

  在 consumer 服务的 SpringRabbitListener 中添加三个方法,作为消费者:

package cn.itcast.mq.listener;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.time.LocalTime;
import java.util.Locale;

/**
 * @author 温柔哥
 * @create 2024-02-01 16:01
 */
@Component
public class SpringRabbitListener {

    // 模拟发布订阅模型之 Fanout
    // 消费者1和消费者2绑定到 queue1
    @RabbitListener(queues = "fanout.queue1")
    public void listenFanoutQueue1(String message) {
        System.out.println("消费者1接受到 fanout.queue1 的消息:【" + message + "】");
    }
    @RabbitListener(queues = "fanout.queue1")
    public void listenFanoutQueue2(String message) {
        System.out.println("消费者2接受到 fanout.queue1 的消息:【" + message + "】");
    }
    // 消费者3绑定到 queue2
    @RabbitListener(queues = "fanout.queue2")
    public void listenFanoutQueue3(String message) {
        System.out.println("消费者3接受到 fanout.queue2 的消息:【" + message + "】");
    }
    
}

  重新启动消费者服务

3.测试发送者发送消息

  在 publisher 服务的 SpringAmqpTest 类中添加测试方法:

// 测试发布订阅模型之 Fanout
@Test
public void testFanoutExchange() {
    String exchangeName = "gentlebrother.fanout";
    String message = "hello everyone!";
    rabbitTemplate.convertAndSend(exchangeName, "", message);
}

  启动测试方法,发送消息

4.分析结果

  结果很明显,并不是每一个消费者都可以接收到消息,而是每一个队列都可以接收到消息,然后每个队列中只能由一个消费者消费

在这里插入图片描述

四、总结

1.交换机的作用是什么?

  • 接收publisher发送的消息
  • 将消息按照规则路由到与之绑定的队列
  • 不能缓存消息,路由失败,消息丢失
  • FanoutExchange的会将消息路由到每个绑定的队列

2.声明队列、交换机、绑定关系的Bean是什么?

  • Queue
  • FanoutExchange
  • Binding
  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值