RabbitMQ之延迟消息实战

RabbitMQ之延迟消息实战

  1. 使用死信交换机实现延迟消息

    使用死信交换机的过期时间以及没有消费者进行消费,时间到了就会到死信队列中,由此可以实现延迟消息
  2. 使用延迟消息插件
    前提:需要mq配置插件

  3. 延时信息案例实战
    把一个30分钟的延迟消息可以拆分成各个小时间段来优化MQ大量信息的压力


    代码实现
    (1)定义消息体对象
java 复制代码
@Data
public class MultyDelayMessage<T>{
	// 消息体
	private T data;
	// 记录延迟时间的集合
	private List<Long> delayMillis;
	
	public MultiDelayMessage(T data List<Long> delayMilis){
		this.data = data;
		this.delayMillis = delayMillis;
	}
	public static <T> MultiDelayMessage<T> of(T data,Long ... delayMillis){
		return new MultiDelayMessage<>(data,Collutils.newArrayList(delayMilis));
	}
	//获取并移除下一个延迟时间,返回队列中的第一个延时时间
	public Long removeNextDelay{
		return delayMillis.remove(0);
	}
	// 判断是否有下一个延时时间
	public bollean hasNextDelay(){
		return !delayMilis.isEmpty();
	}
}

(2)定义队列名称

java 复制代码
public interface MqConstants{
	String DELAY_EXCHANGE = "trade.delay.topic";
	String DELAY_ORDER_QUEUE = "trade.order.delay.queue";
	String DELAY_ORDER_ROUTING_KEY = "order.query"-;
}

(3)创建订单发送延迟消息

java 复制代码
MultiDelayMessage<Long> msg = MultiDelayMessage.of(order.getId(),10000L,10000L,10000L,15000L,15000L,30000L,30000L);
rabbitTemplate.convertAndSend(MqConstants,DELAY_EXCHANGE,DELAY_ORDER_ROUTING_KEY,msg,new MessagePostProcess{
	@Override
	public Message postProcessMessage(Message message) throw AmqpException{
		message.getMessageProperties().setDelay(msg.removeNextDelay().intValue());
	}
});

(4)监听到延迟消息处理订单状态

java 复制代码
@Component
public class OrderStatusChechListenter{
	
	@Autowrid
	private OrderService orderService;

	@RabbitListener(@QueueBinding(value=@Queue(value=MqConstants.DELAY_ORDER_QUEUE,durable="true"),exchange=@Exchange(value=MqConstants.DELAY_EXCHANGE,delayed="true",type=ExchangeTypes.TOPIC),key=MqConstants.DELAY_ORDER_ROUTING_KEY))
public void listenOrderDelayMessage(MultiDelayMessage message){
	// 查询订单支持状态
	Order order = orderService.getById(message.getData());
	if(order == null || order.getStatus == 2){// 已支付
		return;
	}
	// 查询支付服务该订单的支付状态
	boolean isPay = payServive.getById(order.getBussesesId());
	if(isPay){
		// 已支付
		orderService.markOrderPaySuccess(order.getId());
		return;
	}
	// 未支付,并且有延迟时间
	if(msg.hasNextDelay()){
		//重发延迟消息
		Long nextDelay = msg.removeNextDelay();
		rabbitTemplate.convertAndSend(MqConstants,DELAY_EXCHANGE,DELAY_ORDER_ROUTING_KEY,msg,new MessagePostProcess{
	@Override
	public Message postProcessMessage(Message message) throw AmqpException{
		message.getMessageProperties().setDelay(nextDelay.intValue());	}
});
	return;
	}
	// 没有延迟消息,取消订单
	orderService.cancleOrder(order.getId());
	//恢复库存
	orderService.updateStore(order.getId());
}

}
相关推荐
Albert Edison7 小时前
【RabbitMQ】核心概念|工作流程|界面操作
分布式·rabbitmq·ruby
少许极端1 天前
消息队列5-RabbitMQ的高级特性和MQ的应用问题与解决方案-事务、消息分发的应用、幂等性保证、顺序性保证、消息积压的解决
分布式·消息队列·rabbitmq
Arva .1 天前
RabbitMQ
网络·分布式·rabbitmq
小江的记录本1 天前
【RabbitMQ】RabbitMQ核心知识体系全解(5大核心模块:Exchange类型、消息确认机制、死信队列、延迟队列、镜像队列)
java·前端·分布式·后端·spring·rabbitmq·mvc
fzb5QsS1p1 天前
Maomi.MQ 功能强大的 .NET RabbitMQ 消息队列通讯模型框架来了
rabbitmq·.net·ruby
zs宝来了2 天前
RabbitMQ 可靠性投递:持久化、确认机制与死信队列
rabbitmq·死信队列·持久化·可靠性·确认机制
BPM_宏天低代码3 天前
宏天CRM系统的消息中心:基于RabbitMQ的实践
分布式·rabbitmq
少许极端4 天前
消息队列4-RabbitMQ的高级特性-TTL机制、死信队列、延迟队列
分布式·消息队列·rabbitmq
014-code4 天前
RabbitMQ 生产端可靠投递(confirm、return、重试)
分布式·消息队列·rabbitmq
014-code4 天前
RabbitMQ 消费端幂等实战(重复消息、去重、重放怎么处理)
分布式·消息队列·rabbitmq