文章目录
1. 引言
在现代微服务架构中,消息队列已经成为系统解耦、异步处理和数据流控制的重要组件。Spring Boot作为Java生态中最受欢迎的企业级应用开发框架,与RabbitMQ的整合提供了强大而易用的消息处理能力。
本文将从基础概念开始,逐步介绍如何在Spring Boot项目中整合RabbitMQ,包括配置、五种工作模式的实现、高级特性以及最佳实践。
2. RabbitMQ基础回顾
2.1 核心组件
- Producer(生产者):发送消息的客户端应用
- Exchange(交换机):接收生产者消息,并根据路由规则分发到队列
- Queue(队列):存储消息的容器
- Consumer(消费者):接收消息的客户端应用
- Binding(绑定):队列与交换机之间的连接,定义路由规则
2.2 交换机类型
- Direct Exchange:直接交换机,根据RoutingKey完全匹配分发
- Fanout Exchange:扇出交换机,广播模式,忽略RoutingKey
- Topic Exchange:主题交换机,支持通配符匹配
- Headers Exchange:头交换机,根据消息头属性匹配
3. Spring Boot项目搭建
3.1 创建Spring Boot项目
使用Spring Initializr或IDE创建项目,添加以下依赖:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter AMQP -->
<dependency>
<groupIdentity>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- Spring Boot DevTools -->
<dependency>
<groupIdentity>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
3.2 配置文件
在application.yml中配置RabbitMQ连接信息:
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
publisher-confirm-type: correlated
publisher-returns: true
templat:
mandatory: true
server:
port: 8080
4. 基础配置类
4.1 RabbitMQ配置类
package com.example.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
// 消息序列化配置
@Bean
public Jackson2JsonMessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
// RabbitTemplate配置
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(messageConverter());
// 开启确认模式
template.setConfirmCallback((correlationData, ack, cause) -> {
if (ack) {
System.out.println("消息发送成功");
} else {
System.out.println("消息发送失败:" + cause);
}
});
// 开启返回模式
template.setReturnsCallback(returned -> {
System.out.println("消息被回退:" + returned.getMessage());
});
return template;
}
// 监听器容器工厂配置
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(messageConverter());
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); // 手动确认
return factory;
}
}
5. 简单模式(Simple)
5.1 消息实体类
package com.example.rabbitmq.dto;
import java.io.Serializable;
import java.time.LocalDateTime;
public class OrderMessage implements Serializable {
private Long orderId;
private String productName;
private Integer quantity;
private LocalDateTime createTime;
// 构造函数、getter、setter省略
}
5.2 生产者
package com.example.rabbitmq.producer;
import com.example.rabbitmq.dto.OrderMessage;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.UUID;
@Component
public class OrderProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendOrderMessage(String orderInfo) {
// 创建消息属性
MessageProperties properties = new MessageProperties();
properties.setContentType("application/json");
properties.setDeliveryMode(2); // 持久化消息
// 创建消息对象
OrderMessage orderMessage = new OrderMessage();
orderMessage.setOrderId(System.currentTimeMillis());
orderMessage.setProductName("iPhone 15");
orderMessage.setQuantity(1);
orderMessage.setCreateTime(LocalDateTime.now());
// 发送消息
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend("simple.queue", "simple.routing.key",
orderMessage, correlationData);
System.out.println("订单消息发送成功:" + orderMessage);
}
}
5.3 消费者
package com.example.rabbitmq.consumer;
import com.example.rabbitmq.dto.OrderMessage;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class OrderConsumer {
@RabbitListener(queues = "simple.queue")
public void handleOrderMessage(OrderMessage orderMessage, Channel channel, Message message) {
try {
System.out.println("接收到订单消息:" + orderMessage);
// 业务处理逻辑
processOrder(orderMessage);
// 手动确认消息
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
System.err.println("订单处理失败:" + e.getMessage());
try {
// 拒绝消息,不重新入队
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
private void processOrder(OrderMessage orderMessage) {
// 模拟订单处理
System.out.println("正在处理订单:" + orderMessage.getOrderId());
// 这里可以调用订单服务、库存服务等
}
}
5.4 队列声明
package com.example.rabbitmq.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SimpleConfig {
@Bean
public Queue simpleQueue() {
return QueueBuilder.durable("simple.queue")
.build();
}
}
6. 工作队列模式(Work Queue)
6.1 配置类
package com.example.rabbitmq.config;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WorkQueueConfig {
@Bean
public Queue workQueue() {
return QueueBuilder.durable("work.queue")
.build();
}
}
6.2 消费者实现
package com.example.rabbitmq.consumer;
import com.example.rabbitmq.dto.OrderMessage;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class WorkConsumer {
@RabbitListener(queues = "work.queue")
public void worker1(OrderMessage orderMessage, Channel channel, Message message) throws Exception {
System.out.println("Worker1 处理订单:" + orderMessage.getOrderId());
// 模拟处理时间
Thread.sleep(1000);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
@RabbitListener(queues = "work.queue")
public void worker2(OrderMessage orderMessage, Channel channel, Message message) throws Exception {
System.out.println("Worker2 处理订单:" + orderMessage.getOrderId());
// 模拟处理时间
Thread.sleep(1000);
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
}
7. 发布订阅模式(Publish/Subscribe)
7.1 广播交换机和队列配置
package com.example.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FanoutConfig {
// 声明广播交换机
@Bean
public FanoutExchange fanoutExchange() {
return return ExchangeBuilder.fanoutExchange("broadcast.exchange")
.durable(true)
.build();
}
// 邮件队列
@Bean
public Queue emailQueue() {
return QueueBuilder.durable("email.queue")
.build();
}
// 短信队列
@Bean
public Queue smsQueue() {
return QueueBuilder.durable("sms.queue")
.build();
}
// 站内信队列
@Bean
public Queue stationQueue() {
return QueueBuilder.durable("station.queue")
.build();
}
// 绑定邮件队列
@Bean
public Binding emailBinding() {
return BindingBuilder.bind(emailQueue())
.to(fanoutExchange());
}
// 绑定短信队列
@Bean
public Binding smsBinding() {
return BindingBuilder.bind(smsQueue())
.to(fanoutExchange());
}
// 绑定站内信队列
@Bean
public Binding stationBinding() {
return BindingBuilder.bind(stationQueue())
.to(fanoutExchange());
}
}
7.2 消息和消费者
package com.example.rabbitmq.dto;
import java.io.Serializable;
public class PromotionMessage implements Serializable {
private String title;
private String content;
private Long userId;
private String type; // email, sms, station
// 构造函数、getter、setter省略
}
package com.example.rabbitmq.producer;
import com.example.rabbitmq.dto.PromotionMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class PromotionProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void broadcastPromotion(String title, String content, Long userId) {
PromotionMessage message = new PromotionMessage();
message.setTitle(title);
message.setContent(content);
message.setUserId(userId);
// 发送到广播交换机,忽略routing key
rabbitTemplate.convertAndSend("broadcast.exchange", "", message);
System.out.println("促销消息广播成功:" + title);
}
}
package com.example.rabbitmq.consumer;
import com.example.rabbitmq.dto.PromotionMessage;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class PromotionConsumer {
@RabbitListener(queues = "email.queue")
public void emailConsumer(PromotionMessage message, Channel channel, Message msg) throws Exception {
System.out.println("发送邮件:" + message.getTitle());
// 邮件服务逻辑
channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
}
@RabbitListener(queues = "sms.queue")
public void smsConsumer(PromotionMessage message, Channel channel, Message msg) throws Exception {
System.out.println("发送短信:" + message.getTitle());
// 短信服务逻辑
channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
}
@RabbitListener(queues = "station.queue")
public void stationConsumer(PromotionMessage message, Channel channel, Message msg) throws Exception {
System.out.println("发送站内信:" + message.getTitle());
// 站内信服务逻辑
channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
}
}
8. 路由模式(Routing)
8.1 直接交换机和路由配置
package com.example.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RoutingConfig {
// 声明直接交换机
@Bean
public DirectExchange directExchange() {
return ExchangeBuilder.directExchange("log.exchange")
.durable(true)
.build();
}
// 错误日志队列
@Bean
public Queue errorQueue() {
return QueueBuilder.durable("error.log.queue").build();
}
// 警告日志队列
@Bean
public Queue warningQueue() {
return QueueBuilder.durable("warning.log.queue").build();
}
// 信息日志队列
@Bean
public Queue infoQueue() {
return QueueBuilder.durable("info.log.queue").build();
}
// 绑定错误日志队列
@Bean
public Binding errorBinding() {
return BindingBuilder.bind(errorQueue())
.to(directExchange())
.with("error");
}
// 绑定警告日志队列
@Bean
public Binding warningBinding() {
return BindingBuilder.bind(warningQueue())
.to(directExchange())
.with("warning");
}
// 绑定信息日志队列
@Bean
public Binding infoBinding() {
return BindingBuilder.bind(infoQueue())
.to(directExchange())
.with("info");
}
}
8.2 日志服务和消费者
package com.example.rabbitmq.dto;
import java.io.Serializable;
import java.time.LocalDateTime;
public class LogMessage implements Serializable {
private String level; // error, warning, info
private String message;
private String source;
private LocalDateTime timestamp;
// 构造函数、getter、setter省略
}
package com.example.rabbitmq.producer;
import com.example.rabbitmq.dto.LogMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class LogProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void logError(String message, String source) {
LogMessage logMessage = new LogMessage();
logMessage.setLevel("error");
logMessage.setMessage(message);
logMessage.setSource(source);
logMessage.setTimestamp(LocalDateTime.now());
rabbitTemplate.convertAndSend("log.exchange", "error", logMessage);
System.out.println("错误日志发送成功");
}
public void logWarning(String message, String source) {
LogMessage logMessage = new LogMessage();
logMessage.setLevel("warning");
logMessage.setMessage(message);
logMessage.setSource(source);
logMessage.setTimestamp(LocalDateTime.now());
rabbitTemplate.convertAndSend("log.exchange", "warning", logMessage);
System.out.println("警告日志发送成功");
}
public void logInfo(String message, String source) {
LogMessage logMessage = new LogMessage();
logMessage.setLevel("info");
logMessage.setMessage(message);
logMessage.setSource(source);
logMessage.setTimestamp(LocalDateTime.now());
rabbitTemplate.convertAndSend("log.exchange", "info", logMessage);
System.out.println("信息日志发送成功");
}
}
9. 主题模式(Topic)
9.1 主题交换机配置
package com.example.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TopicConfig {
// 声明主题交换机
@Bean
public TopicExchange topicExchange() {
return ExchangeBuilder.topicExchange("news.exchange")
.durable(true)
.build();
}
// 体育新闻队列
@Bean
public Queue sportsQueue() {
return QueueBuilder.durable("sports.news.queue").build();
}
// 财经新闻队列
@Bean
public Queue financeQueue() {
return QueueBuilder.durable("finance.news.queue").build();
}
// 科技新闻队列
@Bean
public Queue techQueue() {
return QueueBuilder.durable("tech.news.queue").build();
}
// 绑定体育队列 (*.sports.*)
@Bean
public Binding sportsBinding() {
return BindingBuilder.bind(sportsQueue())
.to(topicExchange())
.with("*.sports.*");
}
// 绑定财经队列 (*.finance.*)
@Bean
public Binding finance-binding() {
return BindingBuilder.bind(financeQueue())
.to(topicExchange())
.with("*.finance.*");
}
// 绑定科技队列 (*.tech.*)
@Bean
public Binding techBinding() {
return BindingBuilder.bind(techQueue())
.to(topicExchange())
.with("*.tech.*");
}
}
9.2 新闻服务和消费者
package com.example.rabbitmq.dto;
import java.io.Serializable;
public class NewsMessage implements Serializable {
private String category;
private String title;
private String content;
private String source;
// 构造函数、getter、setter省略
}
package com.example.rabbitmq.producer;
import com.example.rabbitmq.dto.NewsMessage;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class NewsProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void publishSportsNews(String title, String content, String source) {
NewsMessage news = new NewsMessage();
news.setCategory("sports");
news.setTitle(title);
news.setContent(content);
news.setSource(source);
rabbitTemplate.convertAndSend("news.exchange", "china.sports.football", news);
System.out.println('体育新闻发布成功:' + title);
}
public void publishFinanceNews(String title, String content, String source) {
NewsMessage news = new NewsMessage();
news.setCategory("finance");
news.setTitle(title);
news.setContent(content);
news.setSource(source);
rabbitTemplate.convertAndSend("news.exchange", "china.finance.stock", news);
System.out.println("财经新闻发布成功:" + title);
}
public void publishTechNews(String title, String content, String source) {
NewsMessage news = new NewsMessage();
news.setCategory("tech");
news.setTitle(title);
news.setContent(content);
news.setSource(source);
rabbitTemplate.convertAndSend("news.exchange", "usa.tech.ai", news);
System.out.println("科技新闻发布成功:" + title);
}
}
10. 高级特性
10.1 延迟队列实现
package com.example.rabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DelayConfig {
// 延迟交换机
@Bean
public DirectExchange delayExchange() {
return ExchangeBuilder.directExchange("delay.exchange")
.durable(true)
.build();
}
// 延迟队列
@Bean
public Queue delayQueue() {
return QueueBuilder.durable("delay.queue")
.withArgument("x-message-ttl", 60000) // TTL 60秒
.withArgument("x-dead-letter-exchange", "dead.exchange")
.withArgument("x-dead-letter-routing-key", "dead")
.build();
}
// 死信队列
@Bean
public Queue deadQueue() {
return QueueBuilder.durable("dead.queue").build();
}
@Bean
public DirectExchange deadExchange() {
return ExchangeBuilder.directExchange("dead.exchange")
.durable(true)
.build();
}
@Bean
public Binding delayBinding() {
return BindingBuilder.bind(delayQueue())
.to(delayExchange())
.with("delay");
}
@Bean
public Binding deadBinding() {
return BindingBuilder.bind(deadQueue())
.to(deadExchange())
.with("dead");
}
}
10.2 消费者限流
package com.example.rabbitmq.config;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AdvancedConfig {
@Bean
public SimpleRabbitListenerContainerFactory advancedContainerFactory(
ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
// 预拉取数量,控制并发
factory.setPrefetchCount(1);
// 消费者数量
factory.setConcurrentConsumers(3);
factory.setMaxConcurrentConsumers(10);
return factory;
}
}
10.3 死信队列处理
package com.example.rabbitmq.consumer;
import com.example.rabbitmq.dto.OrderMessage;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class DeadLetterConsumer {
@RabbitListener(queues = "dead.queue")
public void handleDeadLetter(OrderMessage message, Channel channel, Message msg) throws Exception {
System.out.println("处理死信消息:" + message);
// 记录失败信息到数据库
recordFailure(message);
channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
}
private void recordFailure(OrderMessage message) {
// 记录失败逻辑
System.out.println("订单处理失败,已记录:" + message.getOrderId());
}
}
11. 控制器和测试
11.1 REST API控制器
package com.example.rabbitmq.controller;
import com.example.rabbitmq.dto.OrderMessage;
import com.example.rabbitmq.producer.OrderProducer;
import com.example.rabbitmq.producer.LogProducer;
import com.example.rabbitmq.producer.PromotionProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/mq")
public class MQController {
@Autowired
private OrderProducer orderProducer;
@Autowired
private LogProducer logProducer;
@Autowired
private PromotionProducer promotionProducer;
@PostMapping("/order")
public String sendOrder(@RequestParam String productName, @RequestParam Integer quantity) {
orderProducer.sendOrderMessage("订单信息:" + productName + "," + quantity);
return "订单消息发送成功";
}
@PostMapping("/log")
public String sendLog(@RequestParam String level,
@RequestParam String message,
@RequestParam String source) {
switch (level.toLowerCase()) {
case "error":
logProducer.logError(message, source);
break;
case "warning":
logProducer.logWarning(message, source);
break;
case "info":
logProducer.logInfo(message, source);
break;
default:
return "无效的日志级别";
}
return "日志消息发送成功";
}
@PostMapping("/promotion")
public String broadcastPromotion(@RequestParam String title,
@RequestParam String content,
@RequestParam Long userId) {
promotionProducer.broadcastPromotion(title, content, userId);
return "促销消息广播成功";
}
}
11.2 测试用例
package com.example.rabbitmq;
import com.example.rabbitmq.producer.OrderProducer;
import com.example.rabbitmq.producer.LogProducer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class RabbitMQTest {
@Autowired
private OrderProducer orderProducer;
@Autowired
private LogProducer logProducer;
@Test
public void testSendOrder() {
orderProducer.sendOrderMessage("测试订单");
}
@Test
public void testSendLogs() {
logProducer.logError("系统错误", "UserController");
logProducer.logWarning("内存使用率过高", "SystemMonitor");
logProducer.logInfo("用户登录成功", "AuthService");
}
}
12. 最佳实践
12.1 性能优化建议
- 连接池配置
spring:
rabbitmq:
connection-timeout: 15000
requested-heartbeat: 30
publisher-confirm-type: correlated
publisher-returns: true
listener:
simple:
concurrency: 3
max-concurrency: 10
prefetch: 1
acknowledge-mode: manual
- 消息可靠性保证
- 启用消息确认机制
- 使用持久化消息和队列
- 实现幂等性处理
- 设置合理的重试机制
- 监控和日志
package com.example.rabbitmq.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class MonitoringConfig {
@Bean
public RabbitTemplate monitoringRabbitTemplate(ConnectionFactory connectionFactory,
MessageConverter messageConverter) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(messageConverter);
// 发送确认回调
template.setConfirmCallback((correlationData, ack, cause) -> {
if (ack) {
log.info("消息发送成功:{}", correlationData.getId());
} else {
log.error("消息发送失败:{}, 原因:{}", correlationData.getId(), cause);
}
});
// 发送返回回调
template.setReturnsCallback(returned -> {
log.error("消息被返回:{}", returned.getMessage());
});
return template;
}
}
12.2 错误处理
package com.example.rabbitmq.handler;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler;
import org.springframework.amqp.rabbit.listener.FatalExceptionStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class ErrorHandlerConfig {
@Bean
public ConditionalRejectingErrorHandler errorHandler() {
return new ConditionalRejectingErrorHandler(new FatalExceptionStrategy());
}
// 全局异常处理器
@SlbitListener
public void handleErrors(Exception exception, Channel channel, Message message) {
log.error("消息处理异常:{}", exception.getMessage(), exception);
try {
// 实现重试逻辑或发送到死信队列
retryOrSendToDeadLetter(message, channel);
} catch (Exception e) {
log.error("错误处理失败:{}", e.getMessage());
}
}
private void retryOrSendToDeadLetter(Message message, Channel channel) throws Exception {
// 重试逻辑或死信队列处理
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
}
}
13. 总结
本文详细介绍了Spring Boot与RabbitMQ的整合方案,涵盖了从基础配置到高级特性的完整实现。通过五种工作模式的实际应用,展示了RabbitMQ在不同场景下的最佳实践。
关键要点:
- 配置简化:Spring Boot自动配置功能大大简化了RabbitMQ的集成
- 模式灵活:根据不同业务场景选择合适的工作模式
- 可靠性:通过确认机制、持久化、重试等保证消息可靠性
- 性能优化:合理配置连接池、并发控制、预取数量等参数
- 监控告警:完善的日志记录和异常处理机制
Spring Boot与RabbitMQ的组合为构建高可用、高性能的分布式系统提供了强大的消息处理能力,是现代化企业应用开发的重要技术栈。
11万+

被折叠的 条评论
为什么被折叠?



