记录Redis实现消息队列遇到的一些问题。
首先说为什么用Redis实现消息队列呢?主要是公司的一些业务不是很依赖与MQ,所以没用专门的MQ工具。本次用Reids实现消息队列主要是Redis上手容易,不需要复杂的配置,
其次也是想着解耦和异步。
据了解Redis支持两种方式实现MQ:第一种就是基于List lpush-brpop(rpush-blpop)实现的;
也可以使用rpush和lpush操作入队列,lpop和rpop操作出队列,但是当列表为空时,lpop和rpop会一直空轮询,消耗资源。所以有了上面的改进实现。
brpop和blpop阻塞读,在队列没有消息的时候阻塞,一旦消息来了就醒了。
但是据说阻塞读也有一个问题就是如果阻塞的时间长了,Redis客户端主动断开连接,这个时候阻塞读会抛出异常,所以一般来讲要处理异常并重试。
开发中尝试用这种方式实现MQ发现,这中方式也只能在客户端命令行的方式玩玩,因为出列同入列一样需要不断的调用,试想这一定不是我们要的。
如果非要这么用,那只能轮询了。
第二种基于订阅/发布;publish channel msg/subscribe channel可以一次广播多信道订阅(一个消息可以发布到多个消费者),操作的过程也发现一些缺点就是如果客户端不存在时消息一旦发布就会丢失且不能寻回。该种方式一般用于即时通讯。
开发中遇到的问题是subscribe也是阻塞的,subscribe代码段必须异步执行并且为了不丢失消息要及早执行。
所以我借鉴网上的把订阅的代码单独封装然后通过Thread类run方法执行。