一、需求
基于RabbitMQ的TTL以及死信队列,使用SpringBoot实现延迟付款,手动补偿操作。
1、用户下单后展示等待付款页面
2、在页面上点击付款的按钮,如果不超时,则跳转到付款成功页面
3、如果超时,则跳转到用户历史账单中查看因付款超时而取消的订单。
二、需求分析
1.实现目标分析
- 首先进入首页,首页存在一个按钮,下单按钮,点击触发下单事件
- 下单事件进入到ttl队列,设置过期时间为10s,方便测试。使用ttl队列的弊端是当最外端的消息过期或者消费后才会判断第二个消息的过期时间。我们可以为某一时间内的消息创建新的队列,其中的消息都统一一个过期时间。也就是不同时间段的下单都会创建不同的队列。
- 当rabbitmq-server 确认消费到达,也就是回复消息后,我们跳转到支付页面。
- 支付页面,存在一个支付按钮,点击会发送请求,这时侯会主动去拉取ttl队列中的消息,消费确认后,前端跳转到成功页面。
- 支付页面上会应该要显示倒数过期时间,超时后跳转到历史页面,然后去请求后端,到死信队列中拉取消息,把订单取消了。最后返回订单信息。
2. 环境准备
- 在虚拟机中安装rabbitmq
- 订单队列、死信队列、支付队列(为了解耦)
三、实现
- 先创建ttl队列相关代码,一个订单信息队列,一个支付信息队列,一个死信队列,一个topic交换器,一个死信交换器。支付信息队列设置10s过期。
package com.lagou.config;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitConfig {
/**
* 订单队列
* @return
*/
@Bean public Queue queueOrderpay() {
Map<String, Object> props = new HashMap<>();
// 对于该队列中的消息,设置都等待10s
//props.put("x-message-ttl", 10000);
// 设置队列的空闲存活时间(如该队列根本没有消费者,一直没有使用,队列可以存活多久)
//props.put("x-expires", 10000);
Queue queue = new Queue("q.pay.ttl-order", true, false, false);
return queue;
}
/**
* 支付死信队列
* @return
*/
@Bean public Queue queueDLXpay() {
Queue queue = new Queue("pay.dlx", true, false, false);
return queue;
}
/**
* 支付队列
* @return
*/
@Bean public Queue queueTTLPay() {
Map