延遲處理是乙個非常常用的乙個功能;
例如, 下單成功後,在30分鐘內沒有支付,自動取消訂單;
延遲佇列便是延遲處理中最常見的實現方式;
先一起看下jdk中延遲佇列是如何實現的.
在jdk中, 提供了一套延遲佇列的實現, 是juc包中delayqueue類.
在使用時只需要讓處理的元素物件實現delayed介面, 就可以根據延遲時間實現延遲處理了.
delayqueue佇列內部是用優先佇列實現的, 優先佇列的實現原理可以參考小頂堆.
public class delayqueueextends abstractqueueimplements blockingqueue
元素物件需要實現delayed介面的兩個方法
(1) compareto()
元素自定義方法實現, 根據延時時間, 確定元素在佇列中的位置; 元素剩餘延時時間越小排列越靠前, 反之越靠後;
(2) getdelay()
元素自定義方法實現, 判斷元素剩餘延時時間;
public inte***ce delayed extends comparable
彈出元素時, 會根據元素物件的剩餘延時方法getdelay(), 判斷元素是否應該被彈出; 後續邏輯可以根據業務需要繼續輪詢或休眠等待一段時間.
public e poll()
雖然delayqueue不能滿足分布式要求, 但它卻提供了乙個很好的延遲處理框架, 可以根據不同的底層儲存介質替換priorityqueue實現.
例如, redis中的zset.
在上述delayqueue框架的基礎上, 使用zset代替priorityqueue儲存, 並用延遲時間作為zset的score項, 很容易就能實現乙個分布式的高效能延遲佇列.
利用redis的事件監聽機制, 還有另外一種方式實現延遲處理.
redis可以根據需要, 修改redis.conf配置, 實現對一些事件的監聽, 其中就包括key過期事件.
redis.conf 配置
notify-keyspace-events ex
這個事件監聽是通過pubsub機制實現的, 所以業務**中實現對事件的訂閱, 就可以知道哪個key過期了.
pubsub 主題:
是指redis的database
__keyevent@__:expired
有了上述事件監聽基礎, 將延期事件對應key存入redis, 並根據延遲時間設定key過期時間, 當key過期時, 便能觸發監聽事件, 完成延遲處理邏輯.
當然, 除了上述方式之外, 還可以使用定時任務輪詢, 死信佇列等等方式實現延遲處理
redis過期key監聽
修改配置檔案 redis.conf notify keyspace events ex k 鍵空間通知,以 keyspace 為字首 e 鍵事件通知,以 keysevent 為字首 g del expipre rename 等型別無關的通用命令的通知,string命令 l list命令 s set命...
redis開啟過期監聽
第一步 配置redis的過期失效監聽,需要修改redis.conf配置檔案,找到 event notification 事件通知 這個配置 將notify keyspace events 修改為notify keyspace events ex 引數解釋,看配置檔案或者官網都有詳細解釋,如下 eve...
redis過期事件監聽
1 redis配置檔案修改 redis.windows.conf與 redis.windows service.conf都要修改 notify keyspace events ex2 新增redis配置檔案,訂閱過期事件訊息 keyevent 1 expired 其中1代表操作redis中的db1,...