订单自动过期实现方案 - 转

转 https://blog.csdn.net/qq_26360877/article/details/106184296

需求分析:24小时内未支付的订单过期失效。

解决方案

  1. 被动设置:在查询订单的时候检查是否过期并设置过期状态。
  2. 定时调度:定时器定时查询并过期需要过期的订单。
  3. 延时队列:将未支付的订单放入一个延时队列中,依次取出过期订单。
  4. 过期提醒:reids支持将一个过期的key(订单号)通知给客户端,根据过期的订单号进行相应的处理。

被动设置:

就是在查询的时候判断是否失效,如果失效了就给他设置失效状态

定时调度:

利用一个定时器,在设置的周期内轮询检查并处理需要过期的订单。
具体实现有基于Timer的,有基于Quartz,还有springboot自带的Scheduler

缺点:

(1)不能够精准的去处理过期订单,轮询周期设置的越小,精准度越高,但是项目的压力越大,我们上一个项目就有这种状况,太多定时器在跑,项目运行起来比较笨重。
(2)而且需要处理的是过期的订单,但是要查询所有未支付的订单,范围大。对于大订单量的操作不合适。

@Schedule(cron="0/5 * * * * ?")

       按顺序依次为
      1  秒(0~59)
      2  分钟(0~59)
      3 小时(0~23)
      4  天(0~31)
      5 月(0~11)
      6  星期(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
      7.年份(1970-2099)

eg1: 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点

eg2: 0 15 10 * * ? 2005 2005年的每天上午10:15触发

 

过期提醒:

基于redis的过期提醒功能;

1、修改redis配置开启“过期提醒”   notify-keyspace-events改为notify-keyspace-events "Ex"

2、继承KeyExpirationEventMessageListener ,重写onMessage

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
import java.util.Date;

/**
 * @author mashu
 * Date 2020/5/17 23:01
 */
@Component
public class OrderExpirationListener extends KeyExpirationEventMessageListener {

    public OrderExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        final String expiredKey = message.toString();
        System.out.println("我过期了" + expiredKey+"当前时间:"+new Date());
    }
}

3、向redis中存入一个订单,过期时间为1分钟。

redis.set("orderCode/10010", "1", 1L, TimeUnit.MINUTES);
System.out.println("redis存入订单号 key: orderCode/10010,value:1,过期时间一分钟,当前时间"+new Date());

4、运行

 

 

你可能感兴趣的:(Java)