訂單自動過期實現方案 - 轉

guettp發表於2020-11-01

轉 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、執行

 

 

相關文章