對於多數同窗來講,可能只是用過Redis
的緩存。但這只是其中小小的一部分,其餘的例如非精準去重的計數,活躍量計算,延時隊列等均可以用redis實現。
假設有一個業務場景,須要用到Redis
的隊列,有哪些特色是須要咱們關心的呢?面試
假設使用Redis
List做爲隊列的實現,這時候須要使用while循環消費:redis
while(true){ getMessageFromList() sleep(time) } 複製代碼
若是 time
變量時間設置太小,當list中無數據時,會致使Redis
qps太高。而時間設置太長,消息的延遲性就會很長。因此咱們須要設置一個合適的時間。
上述的方法看似解決了問題,可是不夠靈活。有沒有什麼更好的辦法,可以在消息進入隊列時纔去消費呢?有想到嗎?
Redis阻塞讀就是一個解決的方法。當隊列中沒有數據時,會產生阻塞,直到生產者發送消息到隊列。可是一直阻塞,Redis
服務端通常會斷開鏈接,因此須要在客戶端捕獲Redis拋出的異常。如下是SpringBoot-Data-Redis的寫法緩存
while(true){ System.out.println("start"); List list = redisTemplate.executePipelined(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { List l = connection.bLPop(10,"bpop4".getBytes()); // 10 表明阻塞時間 return null; } }); System.out.println(JSON.toJSONString(list)); } 複製代碼
在RabbitMq
中,生產者發送消息到交換機中時,Exchange
會有Ack機制,通知生產者已經收到消息。在消費者消費到消息時,也有ack機制通知生產者,而且生產者還能進行重試。而使用Redis做爲隊列時,沒法確保消息被消費者正確消費到。所以當你的業務能容許消息的丟失時,能夠嘗試着使用它。bash
在RocketMq
或者kafka
中有着消費者組和消費者的概念。markdown
Redis
的隊列只有集羣模式。 其實除了上述的部分,Redis
做爲隊列還有其餘的不足之處,固然有些問題能夠經過某些技巧解決,像kafka這些內部也只是隊列而已,它們能解決,咱們固然也能。
當咱們在使用某種技術時,要充分考慮到這些不足之處,而不是做爲面試題去考慮。ide