使用redis的zset實現簡單的延時佇列

2022-09-08 00:57:24 字數 1745 閱讀 4110

一、需求切入點

在公司做的乙個系統業務需要有個定時提醒的功能(資料在mysql中),要求提醒的時間差精準到分鐘

解決方案有:

使用定時器,每分鐘執行一次,查符合提醒的資料,發起提醒(資料庫連線與系統的負載都承受不住的!!)

將待提醒資料提前查出存進redis中,根據提醒時間設定過期時間,做redis的過期監聽,監聽到過期的資料再做業務處理(優點 : 不用實時查資料庫,一定程度上減少系統壓力 缺點: 一旦系統重啟或者系統出現異常,可能導致一些過期的資料沒有監聽到,造成資料沒有推送)

使用乙個延時佇列,利用redis的zset(sort set,有序不重複集合,關聯分數score進行排序),將提醒時間作為分數,提取符合條件的score對應的集合發起提醒(本文所述也是圍繞這個方案)

二、延時佇列的基本操作流程基本流程圖

**實現

生產者,只關心資料進佇列

public class messageprovider 

} catch (exception e)

}/**

* 撤回訊息 業務延伸

* @param members

*/public void withdrawmessage(long members)

}

消費者,只關心需要消費的資料

// 從延伸佇列拉取符合消費的資料

listmsglist = delayingqueueservice.pull();

```msglist.stream().foreach(msg ->

```

延時佇列實現

public class delayingqueueservice 

/*** 移除訊息

** @param queuemessage

* @return

*/@sneakythrows

public boolean remove(queuemessage queuemessage)

return remove > 0 ? true : false;

}/**

* 拉取最新需要

* 被消費的訊息

* rangebyscore 根據score範圍獲取 0-當前時間戳可以拉取當前時間及以前的需要被消費的訊息

** @return

*/public listpull()

msglist = strings.stream().map(msg -> catch (jsonprocessingexception e)

return message;

}).collect(collectors.tolist());

} catch (exception e)

return msglist;

}//獲得鎖

public boolean getlock()

public void releaselock()

}

三、結束語本文所述的方法也是存在一些小的缺點,比如,資料的正常操作依賴於第三方元件,如果redis掛掉了,這個服務就down掉了,實現延時佇列的方法有很多種,基於業務與系統本身的情況,相容利弊去做一些取捨,以達到最好的效果

關於redis中Zset元素的使用

zset在set基礎上增加了乙個排序 權值 需手動指定,分數越小,越排前面 zadd zadd name 序號 value 序號2 value2 依據序號的重要程度排序 zrange zrange name start end 查詢zset中的元素,預設從小到大排序,若要從大到小,使用zrevran...

使用redis中的zset實現實時排行榜

redis在業務開發中會被頻繁使用,zset是其中一種特殊用法,zset具排行榜的天然特性,我前幾個月在一次開發中使用到了zset,就是因為涉及到要實現乙個排行榜,那是我第一次用到zset,雖然之前都看過redis幾種資料型別的資料結構及其使用方法,但是真正用起來的時候,還是有一些細節的東西要處理的...

redis 六 redis的zset(有序集合)

相比於set,zset中會有乙個score屬性,用於set的排名。zadd 向zset中新增元素 sorce value zrem 刪除element zscore 獲取score zincrby 增加score zrange 獲取資料,start到end zrank 通過下標獲取排名 127.0....