对于多数同窗来讲,可能只是用过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