Spring AMQP

大家好我是苏麟 今天说一说spring aqmp。

SpringAMQP

SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起 来非常方便。

官方 : Spring AMQP

Spring AMQP_第1张图片

Spring AMQP_第2张图片

Spring AMQP_第3张图片

 依赖

        
        
            org.springframework.boot
            spring-boot-starter-amqp
            ${amqp.version}
        
        
            com.github.luues
            spring-boot-starter-rabbitmq
            1.3.0.5.RELEASE
        

SpringAMQP提供了三个功能:

  • 自动声明队列、交换机及其绑定关系
  • 基于注解的监听器模式,异步接收消息
  • 封装了RabbitTemplate工具,用于发送消息

Basic Queue 简单队列模型

在父工程mq-demo中引入依赖

        
        
            org.springframework.boot
            spring-boot-starter-amqp
        

消息发送

首先配置MQ地址,在publisher服务的application.yml中添加配置:

spring:
  rabbitmq:
    port: 5672
    host: 127.0.0.1 # 主机名
    username: guest # 用户名
    password: guest # 密码
    virtual-host: / # 虚拟主机

然后在publisher服务中编写测试类SpringAmqpTest,并利用RabbitTemplate实现消息发送:

package com.sl;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * springAMQP
 */
@RunWith(SpringRunner.class)
@SpringBootTest
class PublisherApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * Simple 简单队列
     */
    @Test
    void testSimple() {
        //队列名
        String queues = "ty";
        //消息
        String message = "hello ty";
        System.out.println("666");
        //发送信息
        rabbitTemplate.convertAndSend(queues, message);
    }

}

消息接收

首先配置MQ地址,在consumer服务的application.yml中添加配置:

spring:
  rabbitmq:
    port: 5672
    host: 127.0.0.1
    username: guest
    password: guest
    virtual-host: /

然后在consumer服务新建一个类SpringRabbitListener,代码如下:

package com.sl.spring;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;



@Component
public class SpringRabbitMQListener {

    @RabbitListener(queues = "ty")
    public void listenerSimpleQueue(String msg) {
        System.out.println("消费者接收到的消息 : " + msg);
    }
}

测试

启动consumer服务,然后在publisher服务中运行测试代码,发送MQ消息 .

 我们发送消息之前需要自己创建一个队列

Spring AMQP_第4张图片

Spring AMQP_第5张图片

 接受消息

Spring AMQP_第6张图片

WorkQueue 工作队列

Work queues,也被称为(Task queues),任务模型。简单来说就是让多个消费者绑定到一个队列, 共同消费队列中的消息。

Spring AMQP_第7张图片当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,无法及时处理。

此时就可以使用work 模型,多个消费者共同处理消息处理,速度就能大大提高了。

消息发送

这次我们循环发送,模拟大量消息堆积现象。

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

package com.sl;

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * springAMQP
 */
@RunWith(SpringRunner.class)
@SpringBootTest
class PublisherApplicationTests {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * Work 工作队列
     */
    @Test
    void testWork() {
        String queues = "ty";

        for (int i = 0; i <= 50; i++) {
            String message = "hello rabbitmq__";
            rabbitTemplate.convertAndSend(queues, message + i);
        }
    }

}

消息接收

要模拟多个消费者绑定同一个队列,我们在consumer服务的SpringRabbitListener中添加2个新的方 法:

package com.sl.spring;

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @className: SpringRabbitMQListence
 * @author: TianYuan ShowTime
 * @date: 2023/7/29-9:30
 **/

@Component
public class SpringRabbitMQListener {

    /**
     * @RabbitListener 声明队列名称
     */

    @RabbitListener(queues = "ty")
    public void listenerWorkQueue1(String msg) throws InterruptedException {
        System.out.println("消费者1......接收到的消息: " + msg + LocalDateTime.now());
        Thread.sleep(20);
    }

    @RabbitListener(queues = "ty")
    public void listenerWorkQueue2(String msg) throws InterruptedException {
        System.out.println("消费者2......接收到的消息" + msg + LocalDateTime.now());
        Thread.sleep(200);
    }

}

测试

启动ConsumerApplication后,在执行publisher服务中刚刚编写的发送测试方法testWorkQueue。

Spring AMQP_第8张图片

这会耗时

能者多劳

在spring中有一个简单的配置,可以解决这个问题。我们修改consumer服务的application.yml文件, 添加配置:

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

节省了好几秒的时间

总结 : 

Work模型的使用:

  • 多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
  • 通过设置prefetch来控制消费者预取的消息数量

这期就到这里下期见!

你可能感兴趣的:(SpringCloud篇,java,spring,cloud,rabbitmq,后端,分布式)