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一段时间再去重试
把获取锁的请求放到延时队列中,过段时间再去尝试