1. 程式人生 > >使用Redis實現隨機時間任務排程

使用Redis實現隨機時間任務排程

隨機時間任務排程,是指在某個隨機時間之後,觸發相應的任務。

比如某拼團電商場景中,使用者發起拼團後,如果超過一小時沒有人加入,會由系統強制新增虛擬使用者,強制拼團成功。這個排程時間不能是固定的,而是隨機雜湊分佈的,否則會產生虛假感。

以下是用Redis實現的,利用的是redis中zset的排序功能。

首先,需要生成隨機時間。在Java中可以用簡單的隨機演算法,

    public Long forceGroupTimeout(OrderGroup group){
        Map<String,Integer> probability=orderGroupConfig.getForceGroupProbability();
        int rd = random.nextInt(100);
        int delay; //結果數字
        if(rd < probability.get("10-30")){ //10-30分鐘執行機率
            delay = 10+random.nextInt(20);
        }else if(rd < probability.get("30-60")){//30-60分鐘執行機率
            delay = 30+random.nextInt(30);
        }else if(rd < probability.get("60-90")){//60-90分鐘執行機率
            delay = 60+random.nextInt(30);
        }else{
            delay = 90+random.nextInt(30);//90-120分鐘內強制執行
        }
        Long forceTime = System.currentTimeMillis()+(delay*60*1000)+60*60*1000;//此處新增一小時
        return forceTime ;
    }

其中,probability是一個隨機機率的Map,在配置檔案裡配置如下

forceGroupProbability.10-30: 10

forceGroupProbability.30-60: 20

forceGroupProbability.60-90: 30

forceGroupProbability.90-120: 100

表示10-30分鐘執行的機率是10%,30-60分鐘執行的機率是20%,最後一個數可以不用填。

生成的這個時間戳就是我們假定一定時間後將要執行任務的時間,將任務id作為key,時間戳作為value儲存到redis的zset中。

之後,建立每分鐘執行的定時任務,使用zset範圍取值方法取比當前時間戳小的任務id:

 Set<String> result=zsetOperations.rangeByScore(getRedisKey(),0,currentTimestamp);

取出後根據任務id執行相應的任務,執行完後將對應的key移除即可。

zsetOperations.removeRangeByScore(getRedisKey(),0,currentTimestamp);