日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

JAVA 實現延遲隊列的方法

瀏覽:69日期:2022-08-30 10:19:41

延遲隊列的需求各位應該在日常開發的場景中經常碰到。比如:

用戶登錄之后5分鐘給用戶做分類推送; 用戶多少天未登錄給用戶做召回推送; 定期檢查用戶當前退款賬單是否被商家處理等等場景。

一般這種場景和定時任務還是有很大的區別,定時任務是你知道任務多久該跑一次或者什么時候只跑一次,這個時間是確定的。延遲隊列是當某個事件發生的時候需要延遲多久觸發配套事件,引子事件發生的時間不是固定的。

業界目前也有很多實現方案,單機版的方案就不說了,現在也沒有哪個公司還是單機版的服務,今天我們一一探討各種方案的大致實現。

1. Redis zset

這個方案比較常用,簡單有效。利用 Redis 的 sorted set 結構,使用 timeStamp 作為 score,比如你的任務是要延遲5分鐘,那么就在當前時間上加5分鐘作為 score ,輪詢任務每秒只輪詢 score 大于當前時間的 key即可,如果任務支持有誤差,那么當沒有掃描到有效數據的時候可以休眠對應時間再繼續輪詢。

方案優劣:

優點:

簡單實用,一針見血。

缺點:

單個 zset 肯定支持不了太大的數據量,如果你有幾百萬的延遲任務需求,大哥我還是勸你換一個方案; 定時器輪詢方案可能會有異常終止的情況需要自己處理,同時消息處理失敗的回滾方案,您也要自己處理。

所以,sorted set 的方案并不是一個成熟的方案,他只是一個快速可供落地的方案。

2. RabbitMQ隊列

下面說一個可以落地的方案,這個方案也被大多數目前在架構中使用了 RabbitMQ 的項目組使用。不好的一點就是,捆綁 RabbitMQ,當你的架構方案是要用別的 MQ 替換 RabbitMQ 的時候,你就蛋疼了(我現在正在經歷)。

RabbitMQ 有兩個特性,一個是 Time-To-Live Extensions,另一個是 Dead Letter Exchanges。

Time-To-Live Extensions

RabbitMQ允許我們為消息或者隊列設置TTL(time to live),也就是過期時間。TTL表明了一條消息可在隊列中存活的最大時間,單位為毫秒。也就是說,當某條消息被設置了TTL或者當某條消息進入了設置了TTL的隊列時,這條消息會在經過TTL秒后 “死亡”,成為Dead Letter。如果既配置了消息的TTL,又配置了隊列的TTL,那么較小的那個值會被取用。

Dead Letter Exchanges

在 RabbitMQ 中,一共有三種消息的 “死亡” 形式:

消息被拒絕。通過調用 basic.reject 或者 basic.nack 并且設置的 requeue 參數為 false; 消息因為設置了TTL而過期; 隊列達到最大長度。

DLX同一般的 Exchange 沒有區別,它能在任何的隊列上被指定,實際上就是設置某個隊列的屬性。當隊列中有 DLX 消息時,RabbitMQ就會自動的將 DLX 消息重新發布到設置的 Exchange 中去,進而被路由到另一個隊列,publish 可以監聽這個隊列中消息做相應的處理。

由上簡介大家可以看出,RabbitMQ本身是不支持延遲隊列的,只是他的特性讓勤勞的 中國脫發群體 急中生智(為了完成任務)弄出了這么一套可用的方案。

可用的方案就是:

如果有事件需要延遲那么將該事件發送到MQ 隊列中,為需要延遲的消息設置一個TTL; TTL到期后就會自動進入設置好的DLX,然后由DLX轉發到配置好的實際消費隊列; 消費該隊列的延遲消息,處理事件。

方案優劣:

優點:

大品牌組件,用的放心。如果面臨大數據量需求可以很容易的橫向擴展,同時消息支持持久化,有問題可回滾。

缺點:

配置麻煩,額外增加一個死信交換機和一個死信隊列的配置; RabbitMQ 是一個消息中間件,TTL 和 DLX 只是他的一個特性,將延遲隊列綁定在一個功能軟件的某一個特性上,可能會有風險。不要杠,當你們組不用 RabbitMQ 的時候遷移很痛苦; 消息隊列具有先進先出的特點,如果第一個進入隊列的消息 A 的延遲是10分鐘,第二個進入隊列的消息B 的延遲是5分鐘,期望的是誰先到 TTL誰先出,但是事實是B已經到期了,而還要等到 A 的延遲10分鐘結束A先出之后,B 才能出。所以在設計的時候需要考慮不同延遲的消息要放到不同的隊列。另外該問題官方已經給出了插件來支持:插件地址。

3. 基于 Netty#HashedWheelTimer類方法的實現

HashedWheelTimer 是 Netty 中 的一個基礎工具類,主要用來高效處理大量定時任務,且任務對時間精度要求相對不高, 在Netty 中的應用場景就是連接超時或者任務處理超時,一般都是操作比較快速的任務,缺點是內存占用相對較高。

算法思想

HashedWheelTimer 主要還是一個 DelayQueue 和一個時間輪算法組合。

JAVA 實現延遲隊列的方法

Hash Wheel Timer是一個環形結構,可以想象成時鐘,分為很多格子,一個格子代表一段時間(越短Timer精度越高),并用一個List保存在該格子上到期的所有任務。同時一個指針隨著時間流逝一格一格轉動,并執行對應List中所有到期的任務。

以上圖為例,假設一個格子是1s,則整個時間輪能表示的時間段16s。當前任務指向格子2,表明在第2s的時候有任務需要執行。任務列表中有兩個任務,每個任務前面的數字表示圈數。2表示當走到第2圈的時候才會執行,那么整個任務的真正執行時間其實是在12s之后執行,即第二圈走到2的時候。每推進一格,對應的每一個 slot 中的round數都要減一。整體算法就是這么個邏輯。

時間輪設計要點:

tick,一次時間推進,每次推進會檢查/執行超時任務; tickDuration,時間輪推進的最小單元,每隔 tickDuration 會有一次 tick,它決定了時間輪的精確程度; bucket(ticksPerWheel),上圖中的每一隔就是一個bucket,表示一個時間輪可以有多少個tick,它是存儲任務的最小單元; 上層時間輪的 tickDuration 是下層時間輪的表示時間的最大范圍,即:父 tickDuration = 子 tickDuration * 子 bucket 。

需要注意的是,這種方式任務是串行執行的。意味著你如果在時間輪中執行任務且任務耗時較長,將會出現調度超時或者任務堆積的情況。所以要將任務的執行異步化。

算法的要點:

任務并不是直接放在格子中的,而是維護了一個雙向鏈表,這種數據結構非常便于插入和移除; 新添加的任務并不直接放入格子,而是先放入一個隊列中,這是為了避免多線程插入任務的沖突。在每個tick運行任務之前由worker線程自動對任務進行歸集和分類,插入到對應的槽位里面。

Netty 使用數組 + 雙向鏈表的方式來組織時間輪,對于添加/取消操作僅做了記錄,真正的操作實際發生在下一個tick。時間的推進是獨立的線程在做,該線程同時也負責過期任務的執行等操作,可簡單認為此步驟操作為O(n),因為推進線程需要完全遍歷timeouts、cancelledTimeouts與bucket鏈表,在遍歷timeouts時,Netty為了避免任務過多,所以限制每次最多遍歷10萬個,也就是說,一個tick只能規劃10萬個任務,當任務量過大時,會存在超時任務執行時間延遲的現象。

方案優劣:

優點:

實現比較優雅。效率高。

缺點:

無法實現HA和橫向擴展,要么就使用多個時間輪。最重要的是,實現也比較復雜,開發者需要考慮所有可能的情況。目前我了解到的延遲隊列在生產環境下有如上三種實現方式,每一種都有人在使用。當然沒有最好的只有最適合的,你覺得 redis 能滿足需求,就按照最簡單的來,你要是有充足的開發周期,你也可以實現時間輪展現實力。

需求千萬種,變化就一種:給時間都能做。

以上就是JAVA 實現延遲隊列的方法的詳細內容,更多關于JAVA 實現延遲隊列的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本高清不卡一区二区三区视频| 尹人成人综合网| 免费美女久久99| 蜜臀a∨国产成人精品| 一区二区三区四区日韩| 91久久中文| 免费日韩视频| 日韩影院免费视频| 91日韩免费| 久久激情网站| 亚洲大片在线| 综合一区av| 国产精品白浆| 久久久久观看| 久久久久中文| 亚洲黄页一区| 免费在线看一区| 国产日本亚洲| 精品久久久中文字幕| 国产精品原创| 在线一区欧美| 国产精品久久亚洲不卡| 日韩精品永久网址| 亚洲福利一区| 日本一区二区中文字幕| 精品一区二区三区免费看| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 久久精品不卡| 国产美女精品| 国产探花在线精品一区二区| 久久精品免视看国产成人| 免费久久精品| 国产精品1luya在线播放| 亚洲高清成人| 久久国内精品自在自线400部| 欧美日韩视频免费观看| 日本一区二区中文字幕| 亚洲天堂av影院| 四虎精品一区二区免费| 国产日韩欧美一区在线| 蜜桃视频欧美| 国产精品va视频| 自拍日韩欧美| 精品国产日韩欧美精品国产欧美日韩一区二区三区 | 99久久www免费| 97se亚洲| japanese国产精品| 精品亚洲二区| 亚洲深夜av| 高清av不卡| 国产精品手机在线播放| 国产精品丝袜xxxxxxx| 精品国产午夜肉伦伦影院| 三级欧美韩日大片在线看| 国产69精品久久| 欧美一区网站| 亚洲一区欧美| 久久久久久久久丰满| 国产精品午夜av| 亚洲无线观看| 日韩一区二区在线免费| 国产精品99久久久久久董美香| 激情偷拍久久| 国产日韩一区二区三区在线| 国产偷自视频区视频一区二区| 成午夜精品一区二区三区软件| 日韩精品一区二区三区中文 | 日本a口亚洲| 99热精品在线观看| 中文字幕在线官网| 欧美日韩91| 蜜桃视频第一区免费观看| 久久青青视频| 中文字幕日韩亚洲| 亚洲男女av一区二区| 国产精品巨作av| 日韩精品福利一区二区三区| 亚洲欧美日韩高清在线| 欧美一级精品| 日韩国产在线| 美女福利一区二区三区| 久久精品福利| 国产欧美日韩一区二区三区在线| 天堂va蜜桃一区二区三区| 99久久99久久精品国产片果冰| 国产一区二区三区久久久久久久久| yellow在线观看网址| 丝袜亚洲另类欧美| 久久婷婷丁香| 欧美韩日一区| 久久久久伊人| 日本一区二区中文字幕| 国产视频一区在线观看一区免费| 国产99精品| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 久久久久久久久久久妇女| 精品国产一区二区三区av片| 国产精品久久亚洲不卡| 国产日韩中文在线中文字幕 | 精品久久99| 精品一二三区| 久久久久免费| 高清久久精品| 亚洲电影在线| 免费精品视频最新在线| 日本不卡一二三区黄网| 国产剧情一区二区在线观看| 久久av资源| 日韩啪啪电影网| 成人小电影网站| 久久精品成人| 欧美一级专区| 欧美亚洲一级| 国产+成+人+亚洲欧洲在线| 欧洲一区二区三区精品| 久久免费大视频| 在线综合亚洲| 日韩成人一级| 国产欧美高清视频在线| 久久精品国产久精国产爱| 精品伊人久久久| 97精品国产一区二区三区| 黄色网一区二区| 五月天久久777| 伊人久久大香线蕉av超碰演员| 国产在线不卡一区二区三区| 久久久精品国产**网站| 久久精品国产99国产| 日韩啪啪电影网| 99精品在线观看| 蜜桃视频免费观看一区| 欧美日韩调教| 免费在线成人| 日韩影院二区| 爽好多水快深点欧美视频| 国产精品入口久久| 四虎884aa成人精品最新| 亚洲一区二区日韩| 国产一区二区亚洲| 少妇久久久久| 日本aⅴ免费视频一区二区三区| 久久精品九色| 鲁大师成人一区二区三区| 免费在线亚洲欧美| 亚洲一区二区免费看| 久久99偷拍| 丝袜国产日韩另类美女| 国产成人免费视频网站视频社区| 亚洲成人一区| 国产高清视频一区二区| 久久久久亚洲| 国产精品极品| 六月丁香综合| 国产资源在线观看入口av| 欧美日韩激情在线一区二区三区| 日韩美女精品| 日韩激情一区| 亚洲日本国产| 成人美女视频| 日本99精品| 日韩精品欧美| 日本h片久久| 国产伊人精品| 欧美日韩一区自拍| 国产一区二区三区天码| 成人国产精选| 亚洲精品三级| 国产精品对白久久久久粗| 日韩久久精品网| 影院欧美亚洲| 欧美亚洲一区二区三区| 国精品一区二区三区| 国产精品地址| 色综合视频一区二区三区日韩 | 久久久免费人体| 欧美精品一区二区久久| 日韩av在线免费观看不卡| 免费看av不卡| 亚洲一区中文| 国产精品99久久久久久董美香| 国产va免费精品观看精品视频| 亚洲欧洲av| 国产欧美日韩一级| 亚洲午夜一级| 精品久久久久久久| 久久成人亚洲| 偷拍欧美精品| 国产aⅴ精品一区二区四区| 国产欧美日韩影院| 爽好久久久欧美精品| 欧美福利一区| 国产精品精品| 国产毛片精品| 亚洲欧美久久精品| 亚洲欧美日韩国产一区| 国产日韩一区| 日韩影院免费视频| 亚洲综合精品四区| 99久久久久国产精品| 久久69成人|