实战基于Redis实现阻塞队列

日常需求开发过程中,不免会遇到需要通过代码进行异步处理的情况,比如批量发送邮件,批量发送短信,数据导入,为了减少用户的等待,不希望一直菊花转啊转,因此需要进行异步处理,做法就是讲要处理的数据添加到队列当中,然后按照排队的先后顺序进行异步处理 。
这个队列,可以是专业的消息队列,如 RocketMQ/RabbitMQ 等,一般项目中,如果只是为了进行异步,未免有点杀鸡用牛刀的意味 。
也可以使用基于 JVM 内存实现队列,但是如果项目进行了重启,就会造成队列数据丢失 。
大部分的项目都会用到 redis 中间件作为缓存使用,此时使用 Redis 的 list 结构来实现队列则是非常合适的选择 。
因此,本文主要讲解基于 Redis 的方式实现异步队列 。
基于 Redis 的 list 实现队列的方式也有多种,先说第一种不推荐的方式,即使用 LPUSH 生产消息,然后 while(true) 中通过 RPOP 消费消息,这种方式的确可以实现,但是不断代码不断的轮询,势必会消耗一些系统的资源 。
第二种方式也是不推荐的方式,也是通过 LPUSH 生产消息,然后通过 BRPOP 进行 阻塞地 等待并消费消息,这种方式较第一种方式减少了无用的轮询,降低系统资源的消耗,但是可能会存在队列消息丢失的情况,如果取出了消息然后处理失败,这个被取出的消息就将丢失 。
第二种方式就是下文要介绍的方式,首先也是通过 LPUSH 生产消息,然后通过 BRPOPLPUSH 阻塞 地等待 list 新消息到来,有了新消息才开始消费,同时将消息备份到另外一个 list 当中,这种方式具备了第二种方式的优点,即减少了无用的轮询,同时也对消息进行了备份不会丢失数据,如果处理成功,可以通过 LREM 对备份的 list 中当前的这条消息进行删除处理 。这种方式实现方式可以参考 


    推荐阅读