大家好我是苏麟 今天说一说spring aqmp。
SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起 来非常方便。
官方 : Spring AMQP
依赖
org.springframework.boot
spring-boot-starter-amqp
${amqp.version}
com.github.luues
spring-boot-starter-rabbitmq
1.3.0.5.RELEASE
SpringAMQP提供了三个功能:
在父工程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消息 .
我们发送消息之前需要自己创建一个队列
接受消息
Work queues,也被称为(Task queues),任务模型。简单来说就是让多个消费者绑定到一个队列, 共同消费队列中的消息。
当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,无法及时处理。
此时就可以使用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中有一个简单的配置,可以解决这个问题。我们修改consumer服务的application.yml文件, 添加配置:
spring:
rabbitmq:
listener:
simple:
prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息
节省了好几秒的时间
Work模型的使用:
这期就到这里下期见!