前言

首先要明确消息队列的作用:异步、解耦、削峰

就算平时开发中,没有大流量,解耦和异步几乎也是离不开的,这就体现了MQ的重要性

但是,总有公司不用啊,但是Redis总用吧,Redis的List结构非常适合用来作消息队列

使用Redis实现消息队列有两种方式

  1. Redis队列模式
  2. Redis发布订阅模式

原理

我们需要了解Redis的命令

Redis的List有两种命令方式,均满足先进先出的队列模式

  1. lpush rpop:非阻塞式
  2. lpush brpop:阻塞式

lpush rpop

127.0.0.1:6379[2]> lpush testmq a b c		//创建队列
(integer) 3
127.0.0.1:6379[2]> lrange testmq 0 -1		//查看value
1) "c"
2) "b"
3) "a"
127.0.0.1:6379[2]> rpop testmq				//取值
"a"
127.0.0.1:6379[2]> rpop testmq				//...
"b"
127.0.0.1:6379[2]> rpop testmq				//...
"c"
127.0.0.1:6379[2]> lrange testmq 0 -1		//已经没有数据了
(empty list or set)
127.0.0.1:6379[2]> keys *					//没有值时,队列会被删除
(empty list or set)
127.0.0.1:6379[2]> rpop testmq				//但是还可以取值
(nil)

lpush brpop

127.0.0.1:6379[1]> brpop testmq 0			//执行brpop命令,但是并没有key=testmq的队列,陷入阻塞中
127.0.0.1:6379[1]> lpush testmq a b			//这里打开了一个新的cli,并向testmq中插入数据a b
(integer) 2
127.0.0.1:6379[1]>
127.0.0.1:6379[1]> brpop testmq 0			//在看原来的cli,可以看出,已经取到值了,还可以看到等待了多久
1) "testmq"
2) "a"
(201.71s)
127.0.0.1:6379[1]> lrange testmq 0 -1		//查看testmq,可以看出a已经被取走
1) "b"

127.0.0.1:6379[1]> keys *
(empty list or set)
127.0.0.1:6379[1]> lpush testmq a			//向testmq中添加a
(integer) 1
127.0.0.1:6379[1]> lpush testmq2 b			//向testmq2中添加b
(integer) 1
127.0.0.1:6379[1]> lrange testmq 0 -1		//查看testmq
1) "a"
127.0.0.1:6379[1]> lrange testmq2 0 -1		//查看testmq2
1) "b"
127.0.0.1:6379[1]> brpop testmq2 testmq 0	//brpop可以接收多个key,会按照顺序读取,这里可以实现一个优先级的功能,这里可以看出接收了testmq2的value
1) "testmq2"
2) "b"

从命令中可以看出,brpop可以接收多个键,意义是同时检测多个键,如果所有键都没有元素,则阻塞,如果其中一个有元素则从该键中弹出该元素,只弹出一个消息.

(会按照key的顺序进行读取,可以实现具有优先级的队列)。

代码

消费者

并没有内置消费者监听器来实现,可以直接使用定时器实现

@Component
public class MsgTask {

    @Resource
    private RedisTemplate redisTemplate;

    @Scheduled(cron="*/5 * * * * *")
    public void sendMsg() {
        Object listMQ = redisTemplate.opsForList().rightPop("listMQ", 0, TimeUnit.SECONDS);
        System.out.println(listMQ.toString());
    }
}

然后使用普通的添加方法就实现了这个简单的消息队列了

redisTemplate.opsForList().leftPush("listMQ","a");

参考

文章1:https://blog.csdn.net/qq_42175986/article/details/88417023

文章2:https://springboot.io/t/topic/1013

文章3:https://yampery.github.io/2019/01/05/redis/rdsmq/

文章4:https://www.jianshu.com/p/d32b16f12f09