Redis-異步消息

關於異步消息,你們都知道,以下:redis

 

  這些用起來都是比較複雜的,RabbitMQ先要建立Exchange,在建立Queue,還要將Queue和Exchange經過某種規則綁定起來。發消息以前要指定routing-Key,還要控制頭部信息。服務器

  即便你只須要一組消息者。那麼你就要經歷上面繁瑣的過程。數據結構

  可是Redis對於那些輕量級和只有一組消息者的消息隊列;併發

  Redis的list數據結構經常使用來做爲異步消息隊列來使用。使用rpush/lpush操做入隊列,用lpop/rpop來出隊列。咱們都知道list是一個鏈表,因此操做方式以下異步

 

 

 固然咱們會遇到一些問題,好比隊列空了會怎麼樣?客戶端是經過隊列的 pop 操做來獲取消息,而後進行處理。處理完了再接着獲取消息,再進行處理。如此循環往復,這即是做爲隊列消費者的客戶端的生命週期。 但是若是隊列空了,客戶端就會陷入 pop 的死循環,不停地 pop,沒有數據,接着再 pop,又沒有數據。這就是浪費生命的空輪詢。空輪詢不但拉高了客戶端的 CPU,redis 的 QPS 也會被拉高,若是這樣空輪詢的客戶端有幾十來個,Redis 的慢查詢可能會顯著增多。 一般咱們使用 sleep 來解決這個問題,讓線程睡一會,睡個 1s 鍾就能夠了。不但客戶端的 CPU 能降下來,Redis 的 QPS 也降下來了。(摘自Redis深度歷險) 線程

 睡眠會致使消息的延遲增大·,多個消費者狀況下,延遲會有所降低,由於每一個消費者都是的睡眠時間是岔開來的。經過阻塞讀:blocking,也就是這兩個命令:blpop,brpop。blog

固然還有會空閒鏈接自動斷開,顧名思義,一直阻塞,Redis客戶端就成了閒置的,時間長了,服務器會斷開鏈接,減小閒置資源,這時候就會拋出異常,因此編寫消費者的時候,注意捕獲異常,重試。生命週期

延時隊列:隊列

這種方式比較適合異步消息處理,將當前衝突的請求扔到另外一個隊列延後處理以避開衝突資源

咱們將消息序列化成一個字符串做爲 zset 的 value,這個消息的到期處理時間做爲 score,而後用多個線程輪詢 zset 獲取到期的任務進行處理,多個線程是爲了保障可用性,萬一掛了一個線程還有其它線程能夠繼續處理。由於有多個線程,因此須要考慮併發爭搶任務,確保任務不能被屢次執行。

相關文章
相關標籤/搜索