以下是关于如何在 Spring Boot 项目中使用 RabbitMQ 的详细指南,涵盖核心概念、配置、代码实现及使用场景。
1. RabbitMQ 核心概念
- 消息队列 (Message Queue):消息的存储容器,生产者发送消息到队列,消费者从队列中消费消息。
- 交换机 (Exchange):接收生产者发送的消息,并根据路由规则将消息分发到队列。
- 绑定 (Binding):定义交换机和队列之间的路由规则(通过路由键
routingKey
)。 - 消息确认 (Ack/Nack):确保消息可靠投递的机制(手动确认或自动确认)。
RabbitMQ 是一个开源的消息代理(Message Broker),基于 AMQP 协议实现异步通信。核心概念:
- Producer:消息生产者
- Consumer:消息消费者
- Queue:消息存储队列
- Exchange:路由消息到队列的组件
- Binding:交换机和队列的绑定规则
2. 通过 Docker 安装(推荐)
# 拉取镜像
docker pull rabbitmq:3-management
# 启动容器(包含Web管理界面)
docker run -d --name rabbitmq \
-p 5672:5672 \ # AMQP协议端口
-p 15672:15672 \ # Web管理界面端口
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin \
rabbitmq:3-management
3. Spring Boot 集成 RabbitMQ
步骤 1:添加依赖
在 pom.xml
中添加 Spring Boot 的 RabbitMQ 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
步骤 2:配置 RabbitMQ 连接
在 application.yml
中配置 RabbitMQ 连接信息:
spring:
rabbitmq:
host: localhost # RabbitMQ 服务器地址
port: 5672 # 默认端口
username: guest # 默认用户名
password: guest # 默认密码
virtual-host: / # 虚拟主机
4. 发送消息(生产者)
定义交换机和队列
在配置类中声明交换机和队列的 Bean:
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
// 定义队列
@Bean
public Queue demoQueue() {
return new Queue("demo.queue", true); // 队列名 + 是否持久化
}
// 定义直连交换机
@Bean
public DirectExchange demoExchange() {
return new DirectExchange("demo.exchange");
}
// 绑定交换机和队列
@Bean
public Binding binding(Queue demoQueue, DirectExchange demoExchange) {
return BindingBuilder.bind(demoQueue).to(demoExchange).with("demo.routingKey");
}
}
发送消息
使用 RabbitTemplate
发送消息:
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MessageProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendMessage(String message) {
// 发送到交换机,指定路由键
rabbitTemplate.convertAndSend("demo.exchange", "demo.routingKey", message);
System.out.println("消息已发送: " + message);
}
}
5. 接收消息(消费者)
监听消息
使用 @RabbitListener
注解监听队列:
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class MessageConsumer {
// 监听指定队列
@RabbitListener(queues = "demo.queue")
public void handleMessage(String message) {
System.out.println("收到消息: " + message);
// 业务处理逻辑
}
}
6. 交换机类型及使用场景
(1) 直连交换机 (Direct Exchange)
- 路由规则:精确匹配
routingKey
。 - 场景:订单处理(如
order.created
路由到订单队列)。 - 使用:可以指定那些队列可以接受到交换机里面的消息。
@Bean
public DirectExchange orderExchange() {
return new DirectExchange("order.exchange");
}
@Bean
public Binding orderBinding(Queue orderQueue, DirectExchange orderExchange) {
return BindingBuilder.bind(orderQueue).to(orderExchange).with("order.created");
}
(2) 主题交换机 (Topic Exchange)
- 路由规则:通配符匹配(如
user.*
匹配user.created
或user.deleted
)。 - 场景:日志分类(如
logs.error
和logs.info
)。 - 使用:通过主题来可以指定那些队列接受那些交换机里面的信息。
@Bean
public TopicExchange logExchange() {
return new TopicExchange("log.exchange");
}
@Bean
public Binding logBinding(Queue logQueue, TopicExchange logExchange) {
return BindingBuilder.bind(logQueue).to(logExchange).with("logs.#");
}
(3) 广播交换机 (Fanout Exchange)
- 路由规则:广播到所有绑定的队列,忽略
routingKey
。 - 场景:通知广播(如系统公告)。
- 使用: 会通知到每个和广播交换机绑定的队列。
@Bean
public FanoutExchange notificationExchange() {
return new FanoutExchange("notification.exchange");
}
@Bean
public Binding notificationBinding(Queue emailQueue, FanoutExchange notificationExchange) {
return BindingBuilder.bind(emailQueue).to(notificationExchange);
}
7. 高级配置
(1) 消息确认机制
在 application.yml
中开启手动确认:
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: manual # 手动确认
在消费者中手动确认消息:
@RabbitListener(queues = "demo.queue")
public void handleMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) {
try {
System.out.println("收到消息: " + message);
channel.basicAck(tag, false); // 确认消息
} catch (IOException e) {
channel.basicNack(tag, false, true); // 拒绝并重新入队
}
}
(2) 消息重试
配置重试策略:
spring:
rabbitmq:
listener:
simple:
retry:
enabled: true
max-attempts: 3 # 最大重试次数
initial-interval: 1000 # 初始重试间隔(ms)
(3) 死信队列 (DLX)
定义死信队列和绑定:
@Bean
public Queue demoQueue() {
return QueueBuilder.durable("demo.queue")
.withArgument("x-dead-letter-exchange", "dead.letter.exchange") // 绑定死信交换机
.withArgument("x-dead-letter-routing-key", "dead.letter.routingKey")
.build();
}
8. 运行与测试
- 启动 RabbitMQ 服务:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
- 访问管理界面:
http://localhost:15672
(用户名/密码:guest/guest
)。 - 发送消息:
@SpringBootApplication public class Application implements CommandLineRunner { @Autowired private MessageProducer producer; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) { producer.sendMessage("Hello RabbitMQ!"); } }
9. 注意事项
- 消息序列化:默认使用
SimpleMessageConverter
,复杂对象需配置Jackson2JsonMessageConverter
。 - 错误处理:通过
@RabbitListener(queues = "demo.queue", errorHandler = "customErrorHandler")
自定义错误处理。 - 性能优化:合理设置线程池大小和预取数量(
prefetch
)。
通过以上步骤,你可以在 Spring Boot 项目中轻松集成 RabbitMQ,实现高效可靠的异步通信。