Redis 非同步訊息佇列與延時佇列

2021-10-20 20:00:17 字數 1558 閱讀 4769

非同步訊息佇列

說道訊息佇列,你肯定會想到kafka、rabbitmq等訊息中介軟體,這些專業的訊息中介軟體提供了很多功能特性,當然他的部署使用維護都是比較麻煩的。如果你對訊息佇列沒那麼高要求,想要輕量級的,使用redis就沒錯啦。

redis通過list資料結構來實現訊息佇列.主要使用到如下命令:

廢話補不多說上**:

$redis

=new

redis()

;$redis

->

connect

('127.0.0.1'

,6379);

//傳送訊息

$redis

->

lpush

($list

,$value);

//消費訊息

while

(true

)//業務處理

}catch

(exception$e)

}

上面**會有個問題如果佇列長時間是空的,那pop就不會不斷的迴圈,這樣會導致redis的qps公升高,影響效能。所以我們使用sleep來解決,當沒有訊息的時候阻塞一段時間。但其實這樣還會帶來另乙個問題,就是sleep會導致訊息的處理延遲增加。這個問題我們可以通過blpop/brpop 來阻塞讀取佇列。

blpop/brpop在佇列沒有資料的時候,會立即進入休眠狀態,一旦資料到來,則立刻醒過來。訊息的延遲幾乎為零。用blpop/brpop替代前面的lpop/rpop,就完美解決了上面的問題。

還有乙個需要注意的點是我們需要是用try/catch來進行異常捕獲,如果一直阻塞在那裡,redis伺服器一般會主動斷開掉空鏈結,來減少閒置資源的占用。

延遲佇列

你是否在做電商專案的時候會遇到如下場景:

這個時候我們就需要用到延時佇列了,顧名思義就是需要延遲一段時間後執行。redis可通過zset來實現。我們可以將有序集合的value設定為我們的訊息任務,把value的score設定為訊息的到期時間,然後輪詢獲取有序集合的中的到期訊息進行處理。

實現**如下:

$redis

=new

redis()

;$redis

->

connect

('127.0.0.1'

,6379);

$redis

->

zadd

($delayqueue

,$tts

,$value);

while

(true

)//刪除訊息

$ok=

$redis

.zrem

($delayqueue

,$msg);

if($ok)

}catch

(\exception$e)

}

這裡又產生了乙個問題,同乙個任務可能會被多個程序取到之後再使用 zrem 進行爭搶,那些沒搶到的程序都是白取了一次任務,這是浪費。解決辦法:將 zrangebyscore和zrem使用lua指令碼進行原子化操作,這樣多個程序之間爭搶任務時就不會出現這種浪費了。

Redis應用 非同步訊息佇列與延時佇列

說道訊息佇列,你肯定會想到kafka rabbitmq等訊息中介軟體,這些專業的訊息中介軟體提供了很多功能特性,當然他的部署使用維護都是比較麻煩的。如果你對訊息佇列沒那麼高要求,想要輕量級的,使用redis就沒錯啦。redis通過list資料結構來實現訊息佇列.主要使用到如下命令 廢話補不多說上 r...

Redis應用 非同步訊息佇列與延時佇列

原文 說道訊息佇列,你肯定會想到kafka rabbitmq等訊息中介軟體,這些專業的訊息中介軟體提供了很多功能特性,當然他的部署使用維護都是比較麻煩的。如果你對訊息佇列沒那麼高要求,想要輕量級的,使用redis就沒錯啦。redis通過list資料結構來實現訊息佇列.主要使用到如下命令 廢話補不多說...

Redis實現非同步訊息佇列與延時佇列

說道訊息佇列,你肯定會想到kafka rabbitmq等訊息中介軟體,這些專業的訊息中介軟體提供了很多功能特性,當然他的部署使用維護都是比較麻煩的。如果你對訊息佇列沒那麼高要求,想要輕量級的,使用redis就沒錯啦。redis通過list資料結構來實現訊息佇列.主要使用到如下命令 廢話補不多說上 r...