Redis中怎么实现生产消费模式
本篇文章为大家展示了redis中怎么实现生产消费模式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
网站的建设创新互联公司专注网站定制,经验丰富,不做模板,主营网站定制开发.小程序定制开发,H5页面制作!给你焕然一新的设计体验!已为成都水处理设备等企业提供专业服务。
简单队列实现
那么我们Redis刚好有一个数据类型符合这个就是List。list可以实现队列(先进先出)和栈(先进后出),那么这个list又有两种插入数据的方式:头插法和尾插法。所以我们今天使用的结构是队列,使用尾插法,关键的命令有rpush(尾插)和lpop(头部获取)。如下图所示:
> rpush squeue zhangsan lisi mango #插入队列(integer) 3> lpop squeue #获取队列"zhangsan"> rpush squeue wangwu(integer) 3> lpop squeue"lisi"> lpop squeue"mango"> lpop squeue"wangwu"> lpop squeue #空队列(nil)
上面是rpush/lpop结合使用的例子。还可以使用lpush/rpop结合使用,效果是一样的。
注意:我们这里思考一个问题,在咱们实际开发中我们获取队列数据的时候如果这个队列里面没有任何值了,我们会一直pop,这样我们的程序出现了一个死循环,而且此时的redis会不断的处理服务器的pop指令使之内存增高。
此时mango灵光一闪,每次pop的时候判断,如果队列有值我们获取这个值进行操作,如果队列是空队列,那么我们此时休息三秒钟再请求,emmm,加鸡腿。
> lpop squeue #空队列(nil).......sleep 3s old> lpop squeue...
通过后端程序控制redis服务器休息时间是一个好办法,但是此处有一个问题,如果说服务器在休眠的时候队列突然进来一个值,而此时需要及时反应获取这个值该如何实现呢?
当然,redis早就考虑到这个问题,so提供了一个叫做队列阻塞读,其命令blpop和brpop,就是lpop和rpop的阻塞读方法
blpop [第一个参数:key]... [第二个参数:time]key可以有多个key等待time就是阻塞时间,单位默认为秒
嗯,看似完美的解决了上面的方法
问题又来了,如果说此处设置的时间稍微长一点,阻塞请求的客户端连接再多一点那么会出现下一个问题,那就是空闲连接问题。如果线程一直阻塞在哪里,Redis的客户端连接就成了闲置连接,闲置过久,服务器一般会主动断开连接,减少闲置资源占用。这个时候blpop/brpop会抛出异常来。
所以,鱼与熊掌不可兼得,开发者当注意此处需要捕获异常,然后重新请求。
上面我们介绍了阻塞队列,深知空闲连接会被回收出现异常问题,那么我们可不可以实现延迟队列,我提前一段时间比如5秒获取队列中的元素,当元素记录的时间到达了我再去执行这个值,然后又提前5秒时间去获取队列中的值,依次反复。即可保证我在某一时刻去执行队列中对应时间的值。
我们来分析,首先保证队列是一个有序的我们才能依次执行,这里我们使用ZSet因为它带有排序且不重复,保证客户端没有提交重复数据,那么值保证了,这个排序如何设计呢?我们不能使用'yyyyMMddHHmmssSSS'这种,第一个不适应这个排序类型可能会超出,第二就是每次转换会带来运算转换的消耗,所有这里我们使用时间戳。那么zset提供一个获取某段存在数据指令zrangebyscore,这个指令能够获取到我们想要的数据,然后通过zrem删除zset里面的值即可完成消费。
####假设当前时间戳是0> zadd dqueue 4 zhangsan 8 lisi 12 mango #添加元素(integer) 3####提前获取后5秒的数据> zrangebyscore dqueue -inf 5 withscores #提前获取5秒内的数据1) "zhangsan" #值2) 4.0 #当前排序索引> zrem dqueue zhangsan #消费后删除元素1####当前时间戳来到了5秒,提前5秒获取就加上这个> zrangebyscore dqueue -inf 10 withscores #获取10以内的数据,轮训调用1) "lisi"2) 8.0
上述内容就是Redis中怎么实现生产消费模式,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。
网站标题:Redis中怎么实现生产消费模式
新闻来源:http://ybzwz.com/article/ghceih.html