本文目錄一覽:
php使用redis的有序集合zset實現延遲隊列
延遲隊列就是個帶延遲功能的消息隊列,相對於普通隊列,它可以在指定時間消費掉消息。
我們通過redis的有序集合zset來實現簡單的延遲隊列,將消息數據序列化,作為zset的value,把消息處理時間作為score,每次通過zRangeByScore獲取一條消息進行處理。
然後,我們寫一個php腳本,用來處理隊列中的任務。
TP6隊列think-queue(延時隊列/自動取消訂單/php自動操作)
什麼是延時隊列?顧名思義:首先它要具有隊列的特性,再給它附加一個延遲消費隊列消息的功能,也就是說可以指定隊列中的消息在哪個時間點被消費。
延時隊列在項目中的應用還是比較多的,尤其像電商類平台訂單成功後,在30分鐘內沒有支付,自動取消訂單
外賣平台發送訂餐通知,下單成功後60s給用戶推送短信。
如果訂單一直處於某一個未完結狀態時,及時處理關單,並退還庫存
淘寶新建商戶一個月內還沒上傳商品信息,將凍結商鋪等
……
上邊的這些場景都可以應用延時隊列解決。
1.安裝think-queue
2.安裝redis
3.配置,項目\config\queue.php
4.創建隊列和推送
新增 \app\job\test.php 控制器,在該控制器中添加 fire 方法
fire方法是消息隊列默認調用的方法
5.在項目中進行調用延時隊列方法
6.添加監聽 – 重要必要有這個監聽,Queue::later才有效
Redis使用zset有序集合做延遲隊列
把所有需要在未來執行的任務都添加到有序集合裡面,並將任務的執行時間設置為分值,另外再使用一個進程來查找有序集合裡面是否存在可以立即執行的任務,如果有的話,就從有序集合裡面移除那個任務,並將它添加到適當的任務隊列裡面。
–出自《Redis實戰》
創建函數 addFutureJob,負責將延遲任務添加到有序集合job中。
有序集合里存儲的元素,可以使用json格式保存。
內部結構可以類似如下這種:
參數:
$job: 存儲延遲任務的有序集合的名字,叫job
$queue: 當任務到達執行時間時,轉存到具體的隊列里執行
$fun: 負責執行的函數名稱或匿名函數
$time: 延遲任務執行的具體時間
$parameter: 傳遞的參數
執行腳本後,將存儲到job 這個有序集合里
另一個腳本中,讀取job集合,檢查是否有需要執行的任務
這個函數getQueue()的基本流程是這樣:
(1)根據分數從小到大排列,讀取第一個元素。如果元素不存在返回false
(2) 如果元素任務存在,並且它的分數(執行時間)小於等於當前時間,說明這個任務可以執行了。
(3) json轉化成數組,讀取任務的queue參數,將它添加到指定的隊列里,然後從job中刪除這個任務。
(4) 上述轉移操作時,如果成功,記錄日誌。while繼續循環檢查job有序集合
(5) 如果轉移操作失敗,返回false
(6) 後續沒有要執行的任務時,停止循環,返回false
此處循環讀取也可以使用zrangeByScore()函數,根據分數範圍進行讀取返回集合內的指定元素。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/275899.html