RabbitMQ消息的可靠性

RabbitMQ消息的可靠性

一 生产者的可靠性

  1. 生产者重试
    有时候由于网络问题,会出现连接MQ失败的情况,可以配置重连机制
    注意:SpringAMQP的重试机制是阻塞式的,重试等待的时候,当前线程会等待。
yaml 复制代码
spring:
	rabbitmq:
		connection-timout: 1s #设置MQ的连接超时时间
		templete:
			retry:
				enabled: true #开启超时重试机制
				initial-interval: 100ms #失败后的初始等待时间
				multipier: 1 #失败后下次的等待时长倍数, 下次等待时长=initial-interval*multipier
				max-attempts: 3 #最大重试次数
  1. 生产者确认

    (1)在生产者服务的yaml文件中配置一下内容
yaml 复制代码
spring:
	rabbitmq:
		publisher-confirm-type: correlated #开启publisher confirm机制,并设置为MQ异步回调方式返回回执信息
		publisher-returns: true #开启publisher return机制

(2)配置return-callback

java 复制代码
@Slf4j
@Configuration
public class CommonConfig implements ApplicationContexAware{
	@Override
	public void setApplicationContext(ApplicationContent applicationContext){
		// 获取MQ
		RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
		// 设置returnCallback
		rabbitTemplate.setReturnCallback((message,replyCode,replyText,exchange,routingKey)->{
	log.info("消息发送失败,应答码:{},原因:{},交换机:{},路由键:{},消息:{}",replyCode,replyText,exchange,routingKey,message.toString());
});
	}
}

(3)发送消息,指定消息ID,消息的ConfirmCallback

相比于发布消息,多了消息的confirm

java 复制代码
@Test
public void testPubliserConfir()throw InterupteDException{
	// 创建correlationData
	CorrelationData cd = new CorrelationData(UUID.randowUUID().toString());
	// 给Future添加ConfirmCallback
	cd.getFuture().addCallback(new ListenableFutureCllback<CorelationData.Confirm>(){
	@Override
	public void onFailure(Throwable ex){
		// Future发生异常时的处理逻辑,一般不触发
		log.error("handle message ack fail",ex);
	}
	@Override
	public void onSuccess(CorrelationData.Confirm result){
		// Future接收到回执的处理逻辑
		if(result.isAck()){
			log.debug("发送消息成功,收到ACK");
		}else{
			log.error("发送消息失败,收到NACK,reason:{}",result.getReson());
		}
	}
});
// 发送消息
rabbitTemplate.coverAndSend("hmall.direct","red","hello",cd);
}

二 MQ的可靠性

MQ的持久化可以使用Lazy Queue

(1)通过配置类

java 复制代码
@Bean
public Queue lazyQueue(){
	return QueueBuilder.durable("lazy.queue")// 队列名称
	.lazy()//开启lazy
	bulid();
}

(1)基于注解

java 复制代码
@RabbitListener(queuesToDeclare = @Queue(
	name="lazy.queue",
	durable="ture",
	arguments=@Argument(name="x-queue-mode",value="lazy")
))
public void listenLazyQueue(String msg){
	log.info("接收到 lazy.queue的消息:{}",msg);
}

三 消费者确认

  1. 消费者确认机制

    可以通过配置来进行确认
yaml 复制代码
spring:
	rabbitmq:
		listenner:
			simple:
				prefetch: 1
				acknowledgs-mode: auto #确认机制 none-关闭ack,manual-手动ack,auto-自动
  1. 消费失败处理
    重试机制
yaml 复制代码
spring:
	rabbitmq:
		listenner:
			simple:
				prefetch: 1
				retry:
					enabled: true #开启超时重试机制
					initial-interval: 100ms #失败后的初始等待时间
					multipier: 1 #失败后下次的等待时长倍数, 下次等待时长=initial-interval*multipier
					max-attempts: 3 #最大重试次数
					stateless: true #true为无状态,若业务包含事务,则使用false
					

失败处理策略

代码实现

java 复制代码
@Slf4j
@Configureation
@ConditionalOnProperty(prefix="spring.rabbitmq.listenner.simple.retry",name="enable",havingValue="true")// 只有重试机制是true才生效
public class ErrorConfiguration{
	@Bbean
	public DirectExchange errorExchange(){
		return new DirectExchange("error.direct");
	}
	@Bean
	public Queue errorQueue(){
		return new Queue("error.queue");
	}
	@Bean
	public Binding errorBinding(DirectExchange errorExchange,Queue errorQueue){
		return BindingBuilder.bind(errorQueue).to(errorExchange).with("eooro");
	}
	/**
	* 重试失败处理策略
	* RepublishMessageRecoverer:重试失败后,将消息发送到指定的队列中
	*/
	@Bean
	public MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate){
		log.info("MessageRecoverer 重试失败处理策略配置");
		return new RepublishMessageRecoverer(rabbitTemplate,"error.direct","error");
	}
}

四 业务幂等性

  1. 消息唯一id
  2. 业务判断
相关推荐
好奇的菜鸟2 小时前
Spring Boot 启动时自动配置 RabbitMQ 交换机、队列和绑定关系
spring boot·rabbitmq
好奇的菜鸟3 小时前
RabbitMQ 通道(Channel)详解:方法使用、消息确认与拒绝
分布式·rabbitmq
黄小耶@3 小时前
python如何使用Rabbitmq
分布式·后端·python·rabbitmq
超级无敌暴龙战士(solider)3 小时前
如何保证RabbitMQ的可靠性传输
分布式·rabbitmq
小乖兽技术3 小时前
C++开发基础之使用librabbitmq库实现RabbitMQ消息队列通信
开发语言·c++·rabbitmq
简 洁 冬冬11 小时前
036 RabbitMQ消息确认 死信队列 延时队列
rabbitmq
Jeff-Jiang14 小时前
Kafka、RabbitMQ、RocketMQ对比
kafka·rabbitmq·rocketmq
P.H. Infinity19 小时前
【RabbitMQ】06-消费者的可靠性
分布式·rabbitmq·ruby
P.H. Infinity1 天前
【RabbitMQ】08-延迟消息
分布式·rabbitmq·ruby
架构悟道1 天前
不当愣头青、聊聊软件架构中的那些惯用的保命手段
java·分布式·架构·设计·高可用·可靠性·容错