redis作为消息队列使用

1 了解背景

redis在我们的项目中一般作为缓存使用,在我们团队中偶然听到有在讨论要实现一个消息队列的功能。
领导在向一个负责实现此功能的同事下达要使用redis实现这项功能的时候,好像在沟通中出现了很多问题(注:我们的领导是一个从业Java开发十余年的骨灰级工程师,从我进入到这个项目组后学到了还是很多的东西,所以我对他还是比较崇拜的。至于要实现这个功能的同事,是刚刚入职的,了解不是很多,年龄也是不小了,据说也是工作过好多年的)。当领导初步向同事描述完需求的时候好像处于一种蒙蔽的状态,然后领导只能再进一步的和他说实现方法,至于最后沟通了多少遍我也是记不清了,就差直接给这个同事手把手的敲代码了。
我是因为不停的听他们再讨论这个话题,突然想到要是把这个任务给我,我是否能实现的了。redis做缓存使用我是用过很多了,消息队列我只了解过mq和kafka,redis作为消息队列使用我还真不了解。抱着侥幸的心理,趁着工作间隙赶紧自己去网上搜了一下,初步对这个知识点有了些了解,赶紧记录下来,以防过几天脑子再清零了。

2 redis-消息队列使用

为了简单实现,我直接在之前一个搭好的低配版springBoot项目中直接引入redis做了。
通过在网上的了解,redis能作为消息队列使用的有三种数据格式:

List结构:基于List结构来模拟消息队列
PubSub:基本的点对点消息模型
Stream:较完善的消息队列模型

这边文章先记录一下对List结构的使用吧。。。。。
redis的List结构是一种双向链表的结构,他在头尾添加或者删除节点的时候是非常容易的。
二话不说直接上代码,所有的实现都在这里

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/list/{aa}")
    public void jinSave(@PathVariable("aa") String aa){
        redisTemplate.opsForList().leftPush("myQ",aa);
    }

    @GetMapping("/bb")//开启监听
    public void jinSave(){
        for(;;){
            System.out.println("开始获取数据");
            Object data = redisTemplate.opsForList().rightPop("myQ", 0l, TimeUnit.MINUTES);
            if(null == data){
                System.out.println("监听到的数据为空");
            }else {
                System.out.println("监听到的数据为:"+data);
            }

        }
    }
}

说一下消息队列,肯定要有生产者和消费者,我就写了两个接口分别代表。
“/list/{aa}”接口作为生产者使用,每调用一次就会向队列中插入一个节点,用到的就是push方法,但是push方法有两个,leftPush和rightPush,顾名思义就是在链表的左边插入或者右边插入。使用哪个都可以,注意在出队列的时候在另一边即可。
“/bb”接口作为消费者使用,这里注意在redis命令中有两种出队列命令,分别是(RPOP,LPOP)和(BRPOP,BLPOP),他们的区别是(BRPOP,BLPOP)是线程阻塞的,如果队列中没有消息,他就会一直等待,不会像(RPOP,LPOP)一样如果队列中没有消息直接报空,在java里面不是很友好,如果在redisTemplate.opsForList().rightPop(“myQ”, 0l, TimeUnit.MINUTES)中加入了时间就会自动变为(BRPOP,BLPOP),通过源码即可知道,下面是源码:

/**
	 * Removes and returns last element in list stored at {@code key}.
	 *
	 * @param key must not be {@literal null}.
	 * @return can be {@literal null}.
	 * @see <a href="https://redis.io/commands/rpop">Redis Documentation: RPOP</a>
	 */
	@Nullable
	V rightPop(K key);

/**
	 * Removes and returns last element from lists stored at {@code key}. <br>
	 * <b>Blocks connection</b> until element available or {@code timeout} reached.
	 *
	 * @param key must not be {@literal null}.
	 * @param timeout
	 * @param unit must not be {@literal null}.
	 * @return can be {@literal null}.
	 * @see <a href="https://redis.io/commands/brpop">Redis Documentation: BRPOP</a>
	 */
	@Nullable
	V rightPop(K key, long timeout, TimeUnit unit);

打开redis的windows版,再打开redis的桌面管理工具。
首先调用“/bb”接口打开监听,再调用“/list/{aa}”向队列中添加数据,可以看到redis中有数据的插入和删除,也可看到控制台打印的信息。
注:

1、如果时间设为0的话就会一直阻塞
2、开始测试的时候设置的时间为0,但是还会过5秒就会报redis超时,一顿查找后发现是yml配置文件里面配置的超时时间,这里我是把yml超时时间设长了,好像不是很好,暂时没有找到好的解决办法

over,撒花

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值