前言

Redis 的 list 数据结构常用来做消息队列,通常使用的命令有 lpop/rpop ,还有带阻塞版的 blpop/brpop 等。Laravel 5.3 消息队列也是用的 lpop 取消息,为什么不用阻塞版的 blpop 呢?

blpop 不用一直轮询,还可以同时取多个队列,blpop high low 30,更方便实现队列的优先级。

安全队列和不安全队列

什么是不安全的队列?比如客户端 lpop(统一以 lpop 为例) 从 redis 取出来的 job(任务)还没处理完进程挂掉了或者遇到了异常,由于此时服务器上已经没有副本了,这个 job 就丢失了。这种队列就是不安全的。

Laravel 正是为了保证消息队列的可靠,进程挂掉了或者处理失败还可以重试等,做了比较完善的机制,如取队列的同时把队列放入另一个集合中“暂存”起来。如代码所示,使用 lpop 取出队列,同时 zadd 到另一个集合,使用 redis lua 来保证原子性。

public static function pop()
{
 return <<<'LUA'
-- Pop the first job off of the queue...
local job = redis.call('lpop', KEYS[1])
local reserved = false
 
if(job ~= false) then
-- Increment the attempt count and place job on the reserved queue...
reserved = cjson.decode(job)
reserved['attempts'] = reserved['attempts'] + 1
reserved = cjson.encode(reserved)
redis.call('zadd', KEYS[2], ARGV[1], reserved)
end
 
return {job, reserved}
LUA;
}

具体 Laravel 队列工作原理之前有一篇博文进行了整理,请参考:https://www.jb51.net/article/131414.htm

为什么不用 blpop?

这里为什么不使用阻塞版本的 blpop 呢?

blpop 是阻塞版的 lpop,如果队列没有数据过来,那么在超时时间内就会一直阻塞,直到 rpush 数据到队列,有点类似 http 的长轮询,假如客户端取出数据的这一刻挂了,还没来得及暂存到另外的集合中,那么这个数据就丢失了。

你可能会问为何不跟 lpop 一样用 lua 脚本来处理并保证原子性?这个问题作者在 github 上有回答。(https://github.com/laravel/framework/issues/22939)

Laravel中为什么不使用blpop取队列详析

我们知道 redis lua 脚本实际上就是事务,作者的大意也是说 MULTI/EXEC 包裹起来的 blpop 没有意义,这个时候它“退化”为非阻塞版的。

Redis 官方文档也有说明:

在MULTI/EXEC事务中的BLPOP

BLPOP 可以用于流水线(pipline,批量地发送多个命令并读入多个回复),但把它用在 MULTI / EXEC 块当中没有意义。因为这要求整个服务器被阻塞以保证块执行时的原子性,该行为阻止了其他客户端执行 LPUSH 或 RPUSH 命令。

因此,一个被包裹在 MULTI / EXEC 块内的 BLPOP 命令,行为表现得就像 LPOP 一样,对空列表返回 nil ,对非空列表弹出列表元素,不进行任何阻塞操作。

因此通过 lua 脚本操作 blpop 和 zadd 也没有意义,结论就是:因为没用到阻塞的特性,或者无法保证原子性。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!

P70系列延期,华为新旗舰将在下月发布

3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。

而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?

根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。