一、发送者异常监控
1.1 发送者异常种类
1.基本处理流程

- 补偿(兜底)方案

2.模拟broker宕机:修改发送者端口如5673,然后启动,发送消息,端口不对无法连接主机 - 错误信息:java.net.ConnectException: Connection timed out: connect
- 补偿方案:加入异常处理,如果不可达则返回错误
- 这种错误在发送的时候就已经可以发现,直接将错误返回给调用方即可
@RequestMapping("/direct")
public Object sendEmail(String msg) {
try {
rabbitTemplate.convertAndSend("exchange.direct.springboot.email", "queue.email.routing.key", msg);
return msg;
} catch (AmqpException e) {
System.out.println("发送出现异常:" + e.getMessage());
return "网络中断,请稍后再试";
}
}
3.模拟无交换器异常
- 错误信息
ERROR 4880 — [.200.57.39:5672] o.s.a.r.c.CachingConnectionFactory : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange ‘noExchange’ in vhost ‘/’, class-id=60, method-id=40)
- 错误说明:如果没有交换器并不会报错,只会输出一条日志
- 补偿方案:需要采用发送回调来确认是否成功发送消息
4.模拟无路由异常
- 错误信息:无任何提示,消息直接被丢弃
- 补偿方案:需要采用发送回调来确认是否成功发送消息
1.2 消息发送回调
1. 因为消息是异步发送,所以需要确保消息能正确发送
2. 所以可配置RabbitTemplate然后指定回调信息
3. 步骤01:修改配置文件,配置回调参数
publisher-confirm-type
- org.springframework.boot.autoconfigure.amqp.RabbitProperties#publisherConfirmType
- org.springframework.amqp.rabbit.connection.CachingConnectionFactory.ConfirmType
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: tianxin
password: tianxin
# 开启消息发broker回调
publisher-confirm-type: correlated
# 开启路由消息路由回调
publisher-returns: true
# 强制确认,也可以在代码中开启
template:
mandatory: true
/**
* The type of publisher confirms to use.
*/
public enum ConfirmType {
/**
* Use {@code RabbitTemplate#waitForConfirms()} (or {@code waitForConfirmsOrDie()}
* within scoped operations.
*/
SIMPLE,
/**
* Use with {@code CorrelationData} to correlate confirmations with sent
* messsages.
*/
CORRELATED,
/**
* Publisher confirms are disabled (default).
*/
NONE
}
4.步骤02:配置RabbitTemplate,设置交换器确认回调和路由回调
setConfirmCallback:无论成功与否都会调用
setReturnCallback:错误时才调用
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;
import java.util.Objects;
@Configuration
public class CustomRabbitTemplate {
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate();
// 开启mandatory为true才能触发回调方法,无论消息推送结果如何强制调用回调方法
rabbitTemplate.setMandatory(true);
// 设置连接工厂信息
rabbitTemplate.setConnectionFactory(connectionFactory);
// 消息发broker回调:发送者到broker的exchange是否正确找到
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
System.out.println("setConfirmCallback 消息数据:" + correlationData);
if (Objects.nonNull(correlationData)) {
System.out.println("setConfirmCallback 消息数据:" + correlationData.getReturnedMessage());
}
System.out.println("setConfirmCallback 消息确认:" + ack);
System.out.println("setConfirmCallback 原因:" + cause);
System.out.println("-----------------------------------");
});
// 消息路由回调:从交换器路由到队列是否正确发送
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
System.out.println("setReturnCallback 消息:" + message);
System.out.println("setReturnCallback 回应码:" + replyCode);
System.out.println("setReturnCallback 回应信息:" + replyText);
System.out.println("setReturnCallback 交换器:" + exchange);
System.out.println("setReturnCallback 路由键:" + routingKey);
System.out.println("-----------------------------------");
});
return rabbitTemplate;
}
}
- 路由回调和消息回调
/**
* A callback for publisher confirmations.
*
*/
@FunctionalInterface
public interface ConfirmCallback {
/**

本文介绍了SpringBoot整合RabbitMQ实现消息可靠投递,包括发送者异常监控和消息持久化。在异常监控中,讨论了发送者异常的种类及其补偿方案,如通过回调确保消息发送、处理网络异常等。在消息持久化部分,解释了为何需要持久化以防止消息丢失,并展示了具体实现和补偿机制。
最低0.47元/天 解锁文章
2226

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



