解决方案:rabbitmq使用场景-超时未支付订单处理
解决方案:rabbitmq使用场景-超时未支付订单处理
关键词
-
TTL,死信 TTL Queue—>Dead Letter Exchanges—>Dead Letter Queue
消息的TTL(Time To Live)
消息的TTL就是消息的存活时间。RabbitMQ可以对队列和消息分别设置TTL。对队列设置就是队列没有消费者连着的保留时间,也可以对每一个单独的消息做单独的设置。超过了这个时间,我们认为这个消息就死了,称之为死信。
死信交换器 Dead Letter Exchanges
一个消息在满足如下条件下,会进死信路由,记住这里是路由而不是队列,一个路由可以对应很多队列。 (1) 一个消息被Consumer拒收了,并且reject方法的参数里requeue是false。也就是说不会被再次放在队列里,被其他消费者使用。 (2) 上面的消息的TTL到了,消息过期了。 (3) 队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信路由上。
一、添加订单队列 创建
配置属性:
-
x-message-ttl = 消息的存活时间 (毫秒) x-dead-letter-exchange = 死信交换器名称
二、死信交换器和死信队列 创建
三、下单:将订单信息发送到订单队列(指定了TTL时间)
//1.获取购物车列表 //2.设置订单信息并保存 //3.将订单编号发送到ordercreate_queue中(15s之后未支付,向死信队列中发送,后续取消订单)(此队列绑定死信队列) rabbitTemplate.convertAndSend("", "ordercreate_queue", order.getId());
四、创建监听器 监听死信队列:使用rabbitmq的死信队列,实现超时订单取消
/** * 监听ordertimeout_queue(ordercreate_queue绑定了死信交换器【ordertimeout_queue队列】) * * 15s未支付的订单信息 * */ @Component @RabbitListener(queues = "ordertimeout_queue") public class OrderPayTimeoutListener { /** * 1.不扫码,交易没有在支付宝服务器创建 * 2.扫码不支付,交易已经创建,执行关闭 * * @param orderId * @throws Exception */ @RabbitHandler public void orderTimeoutHandler(String orderId) throws Exception { //1.去支付宝服务器查询该订单的支付状态,只有处于未支付状态(WAIT_BUYER_PAY)才关闭交易 //2.在支付宝服务器关闭该交易 //3.本地关闭订单&记录订单日志&回滚库存&回滚销量 } }