码迷,mamicode.com
首页 > 其他好文 > 详细

4.【Redis系列】Redis的高级应用-延时队列

时间:2020-03-18 10:00:40      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:轻松   激活   通过   red   中间件   qps   怎么   异常   客户端   

原文:4.【Redis系列】Redis的高级应用-延时队列

我们习惯于用rabbitmq和kafka作为消息中间件,来给应用之间增加异步的能力。但是使用过的同学都知道,使用专业的消息中间件使用起来非常复杂,我们实现一个简单的功能都需要大量的操作。有了redis,可以让我解脱出来,使用redis可以非常轻松的搞定,Redis的消息队列不是专业的消息中间件,没有非常高级的特性,如果对消息的可靠性有极高的追求,那么redis的消息中间件可能不适合。

异步消息队列

Redis的列表可以用来处理消息队列,使用rpush和lpush操作入队列,用lpop和rpop用来操作出队列。

> rpush notify-queue apple banana pear
(integer) 3
> llen notify-queue
(integer) 3
> lpop notify-queue
"apple"
> llen notify-queue
(integer) 2
> lpop notify-queue
"banana"
> llen notify-queue
(integer) 1
> lpop notify-queue
"pear"
> llen notify-queue
(integer) 0
> lpop notify-queue
(nil)

上面就是队列的操作使用。

队列空了怎么办

客户端通过pop来获取数据,处理完成,再从队列中获取新的数据,如此循环往复。这就是作为队列消费者的生命周期。

可是如果队列空了怎么办,客户端就会陷入pop的死循环。不停的pop,没有数据,再进行pop。这就是浪费生命的空轮询。空轮询不仅拉高了客户端的cpu,redis的QPS也会被拉高。那么怎么办呢

改进1:通常让线程休息1s,睡醒后再进行拉取。不仅客户端的cpu能够降下来,Redis的QPS也能降下来了。

Thread.sleep(1000)  #JAVA 
队列延时

上面的让客户端睡1秒,虽然能够解决一些问题,但是睡眠会导致消息的延迟。如果单线程让线程睡1s就是延迟1s,如果多个客户端呢?

有没有什么办法可以更好的解决这个问题呢?

当然,可以使用blpop和brpop,也就是阻塞读,堵塞读在没有数据时会进入休眠状态,有数据是立马被激活,消息的延迟性几乎为0。

空连接自动断开

如果线程一直被阻塞在哪里,客户端连接就成了闲置连接,闲置过久,服务器一般会主动断开连接,减少闲置资源占用,这个时候blpop和brpo会抛出异常来,在编写代码时格外注意,还要重试。

锁冲突问题

如果加锁没有成功,一般可以通过3中策略来处理加锁失败:
1.直接抛出异常,通知用户稍后再试。这种一般用于用户的直接请求。
2.sleep一会再重试
3.将请求转移至延迟队列中,过一会再试

4.【Redis系列】Redis的高级应用-延时队列

标签:轻松   激活   通过   red   中间件   qps   怎么   异常   客户端   

原文地址:https://www.cnblogs.com/lonelyxmas/p/12515046.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!