使用 Redis 實現延時隊列

使用 Redis 實現延時隊列

場景描述:訂單在下單之後一定時間內沒有支付,則關閉該訂單

實現方式:用戶下單-> 生成訂單記錄-> 將訂單信息推入延時隊列任務中-> 到時間檢查訂單的支付狀態(未支付則關閉訂單)

使用redis 實現延時隊列 的功能

思路: 用戶在調用延時任務的方法時,需要傳入兩個參數(任務腳本,延時時間)。

通過redis 有序集合來存儲執行時間,每次取出第一個元素,執行時間與當前時間對比,如果小於等於當前時間則執行改腳本。並且移除改元素。
由於redis 集合具有唯一性,所以不能放在一個表裏。

  1. string 類型的message_id 用來實現生成唯一id ,作爲2和3連接的樞紐
  2. 有序集合類型 message_delay 存儲執行時間
  3. hash 類型存儲任務

首先,創建一個queue 文件:

//連接Redis
$redis = new Redis();
$redis->connect('107.0.0.1', 6379);//這裏沒有設置登錄賬號


//這裏只是用來測試,job 應是一個實例
$job = 4;
$delay = 10*60;  //延時時間單位改爲分鐘。
queue($job,$delay,$redis);

//入隊列
function queue($job,$delay,$redis){

    $num = $redis->INCR("message_id");

    $redis->ZADD("message_delay", time()+$delay, $num);

    $redis->HSET("messages",$num,$job);

創建job 文件

//連接Redis
$redis = new Redis();
$redis->connect('107.0.0.1', 6379);//這裏沒有設置登錄賬號

function queuePush($redis){
    $uids_d = $redis->ZRANGE("message_delay", 0, 0, TRUE);//取出一個元素
    foreach($uids_d as $key => $val){
        if($val <= time()){
            //移除delay 和 message 數據
            $redis->zrem("message_delay",$key);
            $redis->HDEL("messages",$key);
           return queuePush($redis);  //遞歸調用
        }else{
            return false;
        }
    }
}

最後將你的 job.php 文件放到定時任務中就可以了。
這裏只是一個實現思路,實際中應該使用面向對象的方法去實現。並且進行優化。

php redis操作命令

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章