RabbitMQ(笔记)

为什么使用RabbitMQ

  • 流量削峰
  • 应用解耦
  • 异步处理

什么是AMQP?

  • 应用间消息通信的一种协议,与语言和平台无关

依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • application.yml

    spring:
    	rabbitmq:
    		host: localhost
    		port: 5672
    		username: guest #自己账号
    		password: guest #自己密码
    		virtual-host: / #虚拟主机
    
  • 注解

    • @RabbitListener(queues = "zbl")

      其中"zbl",为消息队列名称

    • @RabbitHandler

      配合@RabbitListener(queues = "zbl")使用

1.Demo01

  • 创建两个服务
  • 开启RabbitMQ服务
  • 引入依赖
  • 配置文件

代码

登陆RabbitMq服务,创建队列“zbl”

http://ip地址:15672 -->登陆 -->选中导航栏的Queues -->找到下方按钮Add Queue

其中 Name:为队列名称

image-20221111201233216

供应方

    //注入RabbitTemplate
	@Autowired
    private RabbitTemplate rabbitTemplate;

    public void test01() {
        System.out.println("开始向队列中发送一条消息!");
        // zbl:管理中的队列名 message:DragonDawson!:发送的消息
        rabbitTemplate.convertAndSend("zbl", "message:DragonDawson!");
        System.out.println("消息发送完毕!");
    }

消费方

    //@RabbitHandler
	@RabbitListener(queues = "zbl")
    public void test01(String message){
        System.out.println("接收到的消息:"+message);
    }

操作流程:

  1. 先启动供应方,将消息,加入队列
  2. 启动消费方,消息会从队列发送到消费方,并删除自身信息
image-20221111201855482

2.消息发布与订阅

①Fanout(广播)

描述

  • 与之前操作不同的是,将一个消息,同时放入多个队列中,从而分发给不同的消费方

  • 在这里就按需引入“交换机

    image-20221111203013692
  • 那么这里也可以是多个交换机,每个交换机和队列都是相互绑定的

  • 代码测试

    配置类

    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;
    
    @Configuration
    public class MqOrderConfig {
        //交换机
        @Bean
        public FanoutExchange fanoutExchange(){
            return new FanoutExchange("dragon.fanout");
        }
    
        //队列
        @Bean
        public Queue fanOutQueue01(){
            return new Queue("fanout.queue01");
        }
    	//队列和交换机绑定
        @Bean
        public Binding bind01(Queue fanOutQueue01,FanoutExchange fanoutExchange){
            return BindingBuilder.bind(fanOutQueue01).to(fanoutExchange);
        }
    
        //队列
        @Bean
        public Queue fanOutQueue02(){
            return new Queue("fanout.queue02");
        }
    	//队列和交换机绑定
        @Bean
        public Binding bind02(Queue fanOutQueue02,FanoutExchange fanoutExchange){
            return BindingBuilder.bind(fanOutQueue02).to(fanoutExchange);
        }
    }
    

    消息发送

        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        public void testFanoutExchange() {
            // 交换机名称
            String exchangeName = "dragon.fanout";
            // 消息
            String message = "hello, everyone!";
            // 发送消息,参数分别是:交互机名称、RoutingKey(暂时为空)、消息
            rabbitTemplate.convertAndSend(exchangeName, "", message);
        }
    

    消息订阅

        @RabbitListener(queues = "fanout.queue01")
        public void listenFanoutQueue1(String msg) {
            System.out.println("消费者1接收到Fanout消息:【" + msg + "】");
        }
    
        @RabbitListener(queues = "fanout.queue02")
        public void listenFanoutQueue2(String msg) {
            System.out.println("消费者2接收到Fanout消息:【" + msg + "】");
        }
    

②Direct(路由)

描述

和广播对比,多绑定了一个key,根据绑定对应的key去操作消息订阅预发布

代码测试

配置类

    //direct交换机
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("dragon.direct");
    }
	//队列
    @Bean
    public Queue dirOutQueue01(){
        return new Queue("direct.queue01");
    }
	//绑定队列和交换机
    @Bean
    public Binding bind03(Queue dirOutQueue01,DirectExchange directExchange){
        return BindingBuilder.bind(dirOutQueue01).to(directExchange).with("red");
    }

    //队列
    @Bean
    public Queue dirOutQueue02(){
        return new Queue("direct.queue02");
    }
	//绑定队列和交换机
    @Bean
    public Binding bind02(Queue dirOutQueue04,DirectExchange directExchange){
        return BindingBuilder.bind(dirOutQueue04).to(directExchange).with("blue");
    }

消息发送

    @Test
    public void testDirectExchange() {
        // 队列名称
        String exchangeName = "dragon.direct";
        // 消息
        String message = "hello, everyone!";
        // 发送消息,参数分别是:交互机名称、RoutingKey(red)、消息
        rabbitTemplate.convertAndSend(exchangeName, "red", message);
    }

消息订阅

    @RabbitListener( bindings = @QueueBinding(
            value = @Queue("direct.queue01"),
            exchange = @Exchange(value = "dragon.direct",type = ExchangeTypes.DIRECT),
            key = {"red","blue"}
    ))
    public void listenDirectQueue1(String msg) {
        System.out.println("消费者1接收到Fanout消息:【" + msg + "】");
    }

    @RabbitListener( bindings = @QueueBinding(
            value = @Queue("direct.queue02"),
            exchange = @Exchange(value = "dragon.direct",type = ExchangeTypes.DIRECT),
            key = {"yellow","blue"}
    ))
    public void listenDirectQueue2(String msg) {
        System.out.println("消费者2接收到Fanout消息:【" + msg + "】");
    }

在这个过程中,交换机只会绑定red的队列

消息也只会发送到red的服务端

③Topic(话题)

描述

配置类

    //topic交换机
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange("dragon.topic");
    }
    //队列
    @Bean
    public Queue topicQueue04(){
        return new Queue("topic.queue02");
    }

    @Bean
    public Binding bind05(Queue topicQueue04,TopicExchange topicExchange){
        return BindingBuilder.bind(topicQueue04).to(topicExchange).with("dragon.topic");
    }

    //队列
    @Bean
    public Queue topicQueue05(){
        return new Queue("topic.queue03");
    }

    @Bean
    public Binding bind06(Queue topicQueue05,TopicExchange topicExchange){
        return BindingBuilder.bind(topicQueue05).to(topicExchange).with("dawson.#");
    }

消息发送

    @Test
    public void testFanoutExchange() {
        // 队列名称
        String exchangeName = "dragon.topic";
        // 消息
        String message = "hello, everyone!";
        // 发送消息,参数分别是:交互机名称、RoutingKey(暂时为空)、消息
        rabbitTemplate.convertAndSend(exchangeName, "dragon.#", message);
    }

消息订阅

	@RabbitListener( bindings = @QueueBinding(
            value = @Queue("topic.queue02"),
            exchange = @Exchange(value = "dragon.topic",type = ExchangeTypes.TOPIC),
            key = {"dragon.first"}
    ))
    public void listenFanoutQueue1(String msg) {
        System.out.println("消费者1接收到Fanout消息:【" + msg + "】");
    }

    @RabbitListener( bindings = @QueueBinding(
            value = @Queue("topic.queue03"),
            exchange = @Exchange(value = "dragon.topic",type = ExchangeTypes.TOPIC),
            key = {"dawson.FFF"}
    ))
    public void listenFanoutQueue2(String msg) {
        System.out.println("消费者2接收到Fanout消息:【" + msg + "】");
    }
posted @ 2022-11-11 22:55  DawsonDragon  阅读(27)  评论(0)    收藏  举报