日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

redis stream java消息队列_Redis 异步消息队列与延时队列

發布時間:2025/3/15 数据库 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis stream java消息队列_Redis 异步消息队列与延时队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

消息中間件,大家都會想到 Rabbitmq 和 Kafka 作為消息隊列中間件,來給應用程序之間增加異步消息傳遞功能。這兩個中間件都是專業的消息隊列中間件,特性之多超出了大多數人的理解能力。但是這種屬于重量級的應用,使用比較麻煩點。如果是輕量級的,使用 Redis就可以。比如對于那些只有一組消費者的消息隊列,使用 Redis 就可以非常輕松的搞定。Redis 的消息隊列不是專業的消息隊列,它沒有非常多的高級特性,沒有 ack 保證,如果對消息的可靠性沒有極致的要求,那么它可以拿來使用。

異步消息隊列

Redis 的 list(列表) 數據結構常用來作為異步消息隊列使用,使用rpush/lpush操作入隊列,使用lpop 和 rpop來出隊列。rpush 和 lpop 結合 或者lpush 和rpop 結合;

客戶端是通過隊列的 pop 操作來獲取消息,然后進行處理。處理完了再接著獲取消息,再進行處理。如此循環往復,這便是作為隊列消費者的客戶端的生命周期。

問題來了

可是如果隊列空了,客戶端就會陷入 pop 的死循環,不停地 pop,沒有數據,接著再 pop,又沒有數據。這就是浪費生命的空輪詢。空輪詢不但拉高了客戶端的 CPU,redis 的 QPS 也會被拉高,如果這樣空輪詢的客戶端有幾十來個,Redis 的慢查詢可能會顯著增多。 通常我們使用 sleep 來解決這個問題,讓線程睡一會,睡個 1s 鐘就可以了。不但客戶端的 CPU 能降下來,Redis 的 QPS 也降下來了。

新的問題:

用上面睡眠的辦法可以解決問題。但是有個小問題,那就是睡眠會導致消息的延遲增大。如果只有 1 個消費者,那么這個延遲就是 1s。如果有多個消費者,這個延遲會有所下降,因為每個消費者的睡覺時間是岔開來的。 有沒有什么辦法能顯著降低延遲呢?你當然可以很快想到:那就把睡覺的時間縮短點。這種方式當然可以,不過有沒有更好的解決方案呢?當然也有,那就是 blpop/brpop。 這兩個指令的前綴字符b代表的是blocking,也就是阻塞讀。 阻塞讀在隊列沒有數據的時候,會立即進入休眠狀態,一旦數據到來,則立刻醒過來。消息的延遲幾乎為零。用blpop/brpop替代前面的lpop/rpop,就完美解決了上面的問題。

問題喋喋不休:

空閑連接自動斷開 你以為上面的方案真的很完美么?先別急著開心,其實他還有個問題需要解決。 什么問題?—— 空閑連接的問題。 如果線程一直阻塞在那里,Redis 的客戶端連接就成了閑置連接,閑置過久,服務器一般會主動斷開連接,減少閑置資源占用。這個時候blpop/brpop會拋出異常來。 所以編寫客戶端消費者的時候要小心,注意捕獲異常,還要重視。

消息延時隊列

延時隊列可以通過 Redis 的 zset(有序列表) 來實現。我們將消息序列化成一個字符串作為 zset 的value,這個消息的到期處理時間作為score,然后用多個線程輪詢 zset 獲取到期的任務進行處理,多個線程是為了保障可用性,萬一掛了一個線程還有其它線程可以繼續處理。因為有多個線程,所以需要考慮并發爭搶任務,確保任務不能被多次執行。 Redis 的 zrem 方法是多線程多進程爭搶任務的關鍵,它的返回值決定了當前實例有沒有搶到任務,因為 loop 方法可能會被多個線程、多個進程調用,同一個任務可能會被多個進程線程搶到,通過 zrem 來決定唯一的屬主。 同時,我們要注意一定要對 handle_msg 進行異常捕獲,避免因為個別任務處理問題導致循環異常退出。

問題來了:

同一個任務可能會被多個進程取到之后再使用 zrem 進行爭搶,那些沒搶到的進程都是白取了一次任務,這是浪費。解決辦法:Lua是Redis內置腳本,執行Lua腳本時,Redis線程會依次執行腳本中的語句,對于客戶端來說操作是原子性的,將 zrangebyscore 和 zrem 一同挪到服務器端進行原子化操作,這樣多個進程之間爭搶任務時就不會出現這種浪費了。

總結

以上是生活随笔為你收集整理的redis stream java消息队列_Redis 异步消息队列与延时队列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。