前一篇文章《redis訊息佇列》介紹了一種簡單的fifo佇列的實現。
fifo佇列中的訊息一經傳送出去,便從佇列裡刪除。如果由於網路原因消費者沒有收到訊息,或者消費者在處理這條訊息的過程中崩潰了,就再也無法還原出這條訊息。也就是說,fifo佇列不能保證訊息會傳遞成功。
究其原因,在於fifo佇列缺乏訊息確認機制,即消費者向佇列報告訊息已收到或已處理的機制。可靠佇列便是加入了這一機制的訊息佇列。
redis在rpoplpush
命令的文件中提供了一種利用這一命令實現可靠佇列的方式。這個命令可以在從乙個list中獲取訊息的同時把這條訊息複製到另乙個list裡,並且這個過程是原子的。
利用rpoplpush
實現的可靠佇列由兩個列表組成,乙個儲存待處理(pending)的訊息,另乙個儲存處理中(processing)的訊息。
生產者通過lpush
將訊息傳送到待處理列表:
127.0.0.1:6379> lpush queue:pending "message"
消費者使用rpoplpush
從待處理列表獲取訊息,同時將它加入處理中列表:
127.0.0.1:6379> rpoplpush queue:pending queue:processing
"message"
此時這條訊息已經從待處理列表中刪除,並且複製到了處理中列表:
127.0.0.1:6379> lrange queue:pending 0 -1
(empty list or set)
127.0.0.1:6379> lrange queue:processing 0 -1
1) "message"
消費者在收到訊息或者處理完訊息後,使用lrem
命令從處理中列表刪除這條訊息,即完成了訊息確認:
127.0.0.1:6379> lrem queue:processing 1 "message"
使用lrem
而不是rpop
的原因在於,在併發時,不能保證處理中的訊息能按加入列表的先後順序被確認;而rpop
會按順序刪除訊息。
沒有被確認的訊息會一直儲存在處理中列表。如果乙個訊息在處理中列表存在的時間過長,那麼可以認為這個訊息的傳遞或處理失敗了。我們可以設定乙個超時時間,定時掃瞄處理中列表,將超時的訊息重新放回待處理列表等待重新傳遞。
**:
Redis訊息佇列
redis的訊息佇列使用簡單,沒有什麼配置,比activemq要輕量級太多,當然功能也比較簡單,如果只需要簡單的訂閱以及發布,可以考慮使用它。訂閱操作 命令為 subscribe channel channel 如 1 所示,即成功訂閱頻道 redis.blog 發布操作 命令為publish ch...
Redis 訊息佇列
訊息佇列,是在構建大型專案的時候 經常會用到的中間價系統,使用訊息佇列有很多好處,例如 1.實現各元件之間的松耦合。利用訊息系統可以使各個元件之間面向資料,而不是面向具體的介面。2.易於擴充套件。對於訊息系統而言,消費者和生產者都可以橫向擴充套件。提到佇列,很自然的就會想到redis的列表型別,可以...
Redis訊息佇列
redis的訊息佇列使用簡單,沒有什麼配置,比activemq要輕量級太多,當然功能也比較簡單,如果只需要簡單的訂閱以及發布,可以考慮使用它。訂閱操作 命令為 subscribe channel channel 如 1 所示,即成功訂閱頻道 redis.blog 發布操作 命令為publish ch...