RabbitMQ 的使用
怎么在项目中使用 RabbitMQ
- 使用官方的客户端。(推荐)
优点:兼容性好,换语言成本低,比较灵活
缺点:太灵活,要自己去处理一些事情,比如要自己维护管理链接,很麻烦。
- 使用封装好的客户端,比如 Spring Boot RabbitMQ Starter
优点:简单易用,直接配置直接用
缺点:封装的太好了,若没有细致了解可能不知道怎么使用
下面将通过介绍使用 SpringBoot RabbitMQ Starter 的方式来使用 RabbitMQ:
引用的注意点
引用的依赖版本要和 Spring Boot 版本对应。 非常重要!!! 比如 Spring Boot 是 2.7.12 ,那么依赖也要是 2.7.12 或者是接近的。或者查看官方的版本依赖参照。
入门 |使用 RabbitMQ 进行消息传递 (spring.io)
官方文档里的发送消息的测试方法:
package com.example.messagingrabbitmq;
import java.util.concurrent.TimeUnit;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class Runner implements CommandLineRunner {
private final RabbitTemplate rabbitTemplate;
private final Receiver receiver;
public Runner(Receiver receiver, RabbitTemplate rabbitTemplate) {
this.receiver = receiver;
this.rabbitTemplate = rabbitTemplate;
}
@Override
public void run(String... args) throws Exception {
System.out.println("Sending message...");
// 关键点在下一行,这是发送消息的主要代码:
rabbitTemplate.convertAndSend(MessagingRabbitmqApplication.topicExchangeName, "foo.bar.baz", "Hello from RabbitMQ!");
receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);
}
}
基础使用(先使用 SpringBoot 的客户端写一个测试方法)
- 引入依赖 ( SpringBoot 的配置)
<!-- Spring 的消息队列启动器 -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-amqp -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>2.7.2</version>
</dependency>
- 编写配置
# 配置 rabbitmq
rabbitmq:
port: 5672
username: guest
password: guest
host: localhost
- 编写生产者代码
@Component
public class MyMessageProducer {
// 使用启动器自带的 rabbitTemplate,进行消息发送
@Resource
private RabbitTemplate rabbitTemplate;
/**
* 发送消息,指定交换机,路由key,消息
* @param exchange 交换机名称
* @param routingKey 路由键
* @param message 具体发送的消息
*/
public void sendMessage(String exchange, String routingKey, String message) {
// 外部做参数校验
rabbitTemplate.convertAndSend(exchange, routingKey, message);
}
}
- 编写消费者代码
@Component
// 使用@Slf4j注解生成日志记录器
@Slf4j
public class MyMessageConsumer {
// @SneakThrows 注解简化异常处理,
// 底层实际上是给需要抛出检查型异常的方法加上了 try-catch,使用这个注解可以让代码更加简洁
@SneakyThrows
// rabbitMQ 消息监听注解,可以用来接收消息
// 设置队列名称和消息确认模式为手动确认
@RabbitListener(queues = {"code_queue"}, ackMode = "MANUAL")
// 在RabbitMQ中,每条消息都会被分配一个唯一的投递标签,用于标识该消息在通道中的投递状态和顺序。
// 通过使用@Header(AmqpHeaders.DELIVERY_TAG)注解,
// 可以从消息头中提取出该投递标签,并将其赋值给long deliveryTag参数。
public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag){
log.info("receiveMessage message = {}", message);
channel.basicAck(deliveryTag, false);
}
}
要调用上面的方法,还需要提前先把队列创建好:
/**
* 初始化 MQ ,创建相应的测试队列
*/
@Slf4j
public class MqInitMain {
@SneakyThrows
public static void main(String[] args) {
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 队列名称
String EXCHANGE_NAME = "code_exchange";
// 声明交换机,指定交换机名称和类型
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
String queueName = "code_queue";
// 声明队列
channel.queueDeclare(queueName, false, false, false, null);
// 绑定交换机
channel.queueBind(queueName, EXCHANGE_NAME, "my_routingKey");
}catch (Exception e) {
log.info("初始化 MQ 失败:{}" , e);
}
}
}
写一个测试方法:
@SpringBootTest
class MyMessageProducerTest {
@Resource
private MyMessageProducer myMessageProducer;
@Test
void sendMessage() {
String exchange = "code_exchange";
String routingKey = "my_routingKey";
String message = "你好呀!";
myMessageProducer.sendMessage(exchange, routingKey, message);
}
}
启动 Spring Boot 项目后,会显示连接到 RabbitMQ 的连接: