SpringBoot + RabbitMQ 实现"订阅模式"

RabbitMQ官网提供了七种队列模型,分别是:简单队列、工作队列、发布订阅、路由模式、主题模式、RPC模式、发布者确认模式。

SpringBoot + RabbitMQ 实现

本文在SpringBoot+RabbitMQ环境实现"订阅模式"

一、订阅模式

 

SpringBoot + RabbitMQ 实现

特点:

1、X代表交换机,生产者没有将消息直接发送到队列,而是先发送到了交换机。

2、订阅模式的交换机类型为fanout。

3、一个队列可以有多个消费者,但发送到队列的消息只能被其中一个消费。

二、fanout交换机

订阅模式、路由模式、主题模式,它们三者的队列结构是一模一样的,区别就在于"交换机类型的不同",交换机的类型决定了工作模式的特点。订阅模式的交换机类型是fanout,路由模式的交换机类型是direct,主题模式的交换机类型是topic,所以学习RabbitMQ的各种工作模式,掌握各类型交换机的工作特点很重要。而fanout 交换机的特点就是跟广播一样,对消息不作选择地分发给所有绑定的队列。

三、在SpringBoot中的实现

 

SpringBoot + RabbitMQ 实现

下面我们就在SpringBoot中实现一个如上图所示的订阅模式,新建2个项目,一个 rabbitmq-provider (生产者),一个rabbitmq-consumer(消费者)。

> 两个项目的pom依赖和yml配置


    org.springframework.boot
    spring-boot-starter-amqp
    2.2.4.RELEASE
spring:
  rabbitmq:
    host: xxx.xxx.xx.xxx
    port: 5672
    virtual-host: felix-vHost
    username: long.yuan
    password: long.yuan

> 创建两个队列、一个Fanout类型的交换机,将两个队列绑定在交换机上

@Configuration
public class RabbitConfig {

    /**
     * @Title 创建2个队列
     * @Description 创建2个队列
     * @Author long.yuan
     * @Date 2020/2/29 13:12
     * @Param []
     * @return org.springframework.amqp.core.Queue
     **/
    @Bean
    public Queue felixQueueA(){
        return new Queue("felix-queue-A");
    }

    @Bean
    public Queue felixQueueB() {
        return new Queue("felix-queue-B");
    }

    /**
     * @Title 声明一个Fanout类型的交换机
     * @Description Fanout类型的交换机会将消息分发到所有的绑定队列,没有RoutingKey的概念
     * @Author long.yuan
     * @Date 2020/2/29 13:13
     * @Param []
     * @return org.springframework.amqp.core.FanoutExchange
     **/
    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange("felix-fanout-exchange");
    }

    /**
     * @Title 将上面创建的2个队列绑定到交换机
     * @Description 将上面创建的2个队列绑定到交换机
     * @Author long.yuan
     * @Date 2020/2/29 13:15
     * @Param [aMessage, fanoutExchange]
     * @return Binding
     **/
    @Bean
    Binding bindingExchangeA(Queue felixQueueA, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(felixQueueA).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeB(Queue felixQueueB, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(felixQueueB).to(fanoutExchange);
    }
}

> 生产者将消息发到交换机上

@Component
public class Publisher {

    @Autowired
    private AmqpTemplate rabbitTemplate;

    /**
     * @Title 生产者将消息发送到交换机
     * @Description 生产者将消息发送到交换机
     * @Author long.yuan
     * @Date 2020/2/29 13:29
     * @Param [i]
     * @return void
     **/
    public void sendMessage() {
        String message = "发布订阅模式-message";
        System.out.println("发送消息 : " + message);
        rabbitTemplate.convertAndSend("felix-fanout-exchange","",message);
    }
}

> 创建3个消费者,一个消费者监控队列A,其余两个消费者监控队列B

@Component
public class Consumer {
    
    @RabbitListener(queues = "felix-queue-A")
    @RabbitHandler
    public void processA(String message) {
        System.out.println("customerA消费queueA消息成功: " + message);
    }

    @RabbitListener(queues = "felix-queue-B")
    @RabbitHandler
    public void processB1(String message) {
        System.out.println("customerB1消费queueB消息成功: " + message);
    }

    @RabbitListener(queues = "felix-queue-B")
    @RabbitHandler
    public void processB2(String message) {
        System.out.println("customerB2消费queueB消息成功: " + message);
    }
}

四、测试

运行test方法发送消息,启动消费者,看结果

SpringBoot + RabbitMQ 实现

SpringBoot + RabbitMQ 实现

可以看到,消息被同时发送到了A、B两个队列,B队列有两个消费者,但只有其中一个消费者B1消费了消息。

订阅模式的交换机类型是Fanout,Fanout交换机的特点,就决定了订阅模式的工作模式,即消息先发送到交换机,交换机对消息不作选择地分发给所有绑定的队列。

 

感兴趣的小伙伴可以关注一下博主的公众号,1W+技术人的选择,致力于原创技术干货,包含Redis、RabbitMQ、Kafka、SpringBoot、SpringCloud、ELK等热门技术的学习&资料。

SpringBoot + RabbitMQ 实现

你可能感兴趣的:(RabbitMQ,rabbitmq)