redis實現延時佇列的兩種方式

2021-10-18 06:28:57 字數 1558 閱讀 4037

專案中的流程監控,有幾種節點,需要監控每乙個節點是否超時。按傳統的做法,肯定是通過定時任務,去掃瞄然後判斷,但是定時任務有缺點:1,資料量大會慢;2,時間不好控制,太短,怕一次處理不完,太長狀態就會有延遲。所以就想到用延遲佇列的方式去實現。

1,開啟過期key監聽

在redis的配置裡把這個注釋去掉

notify-keyspace-events ex
然後重啟redis

2,使用redis過期監聽實現延遲佇列

繼承keyexpirationeventmessagelistener類,實現父類的方法,就可以監聽key過期時間了。當有key過期,就會執行這裡。這裡就把需要的key過濾出來,然後傳送給kafka佇列。

@component

@slf4j

public

class

rediskeyexpirationlistener

extends

keyexpirationeventmessagelistener

/** * 針對 redis 資料失效事件,進行資料處理

* @param message

* @param pattern

*/@override

public

void

onmessage

(message message,

byte

pattern)

string content = message.

tostring()

;//key的格式為 flag:時效型別:運單號 示例如下

tryelse

if(content.

startswith

(abnconstant.yunda))}

catch

(exception e)

}}

可以看的出來,這種方式其實是很簡單的,但是有幾個問題需要注意,一是,這個盡量單機執行,因為多台機器都會執行,浪費cpu,增加資料庫負擔。二是,機器頻繁部署的時候,如果有時間間隔,會出現資料的漏處理。

1,生產者實現

可以看到生產者很簡單,其實就是利用zset的特性,給乙個zset新增元素而已,而時間就是它的score。

public

void

produce

(integer taskid,

long exetime)

2,消費者實現

消費者的**也不難,就是把已經過期的zset中的元素給刪除掉,然後處理資料。

public

void

consumer()

else})

;}trycatch

(interruptedexception e)}}

});}

可以看到這種方式其實是比上個方式要好的。因為,他的那兩個缺點都被克服掉了。多台機器也沒事兒,也不用再擔心部署時間間隔長的問題。

兩個方式都是不錯的,都能解決問題。碰到問題,多思考,多總結。

迴圈佇列的兩種實現方法

順序儲存結構 示意圖參考嚴蔚敏版 資料結構 順序儲存為何宜選迴圈佇列?佇列的順序表儲存中,除了資料域dat adata data 還應附設兩個座標fro ntfront front和rea rrear rear 用來記錄頭結點和尾結點的位置。對於pop poppo p操作,依靠 fro nt 1 f...

django中簡單使用redis的兩種方式

utils資料夾下,建立redis pool.py import redis pool redis.connectionpool host 127.0.0.1 port 6379 max connections 1000 路由 user urls.py from user import views ...

兩種常用的佇列

與棧相反,佇列是一種先進先出的線性表。它只允許在表的一端進行插入,而在另一端刪除元素。和線性表類似,佇列也可以有兩種儲存表示。用鍊錶表示的佇列簡稱鏈佇列。下面是帶頭結點的單鏈佇列的實現 1 include 2 include 34 typedef char qelemtype 5 單鏈佇列節點 6 ...