Redis的list也可以作爲異步消息隊列來使用,當然,你可以用來處理非重要數據,如果是重要數據的話,建議還是使用專業的MQ消息隊列。
list使用rpush/lpush入隊列、lpop和rpop出隊列。
說白了,就是建立一個循環來不停的通過lpop、rpop來獲取消息,如果list長度爲0,那麼就sleep 1秒後再繼續循環獲取消息。但是,這種編寫代碼方式有個問題,就是假如有N個消費者,那麼每個消費者sleep 1秒的話,那這可是一個很長的時間呢,這會導致list面對大量rpush/lpush時,會快速增長。
這裏用blpop、brpop來取代lpop、rpop命令,因爲b是blocking縮寫即阻塞讀,當隊列沒有數據的時候,隊列進入休眠狀態,當數據到來後則立即處理,且消息的延遲幾乎爲零,這樣就可以完美解決sleep 1秒的問題以及N個消費者sleep 1秒所引發的後果。
這裏注意個問題,如果線程一直阻塞,說明客戶端一直沒有發送消息,那麼服務器可能會主動斷開連接,這個時候blpop/brpop會拋出異常,因此編寫客戶端消費者時注意捕獲異常,還要重試。
擴展
Redis2.8之後,通過set擴展參數來實現獲取鎖、釋放鎖的操作,當獲取鎖失敗之後,通常有3個方式來處理:
直接拋出異常讓用戶自己決定下一步操作
sleep一段時間再去重試
把獲取鎖的請求放到延時隊列中,過段時間再去嘗試