Laravel中为什么不使用blpop取队列详析
发布:smiling 来源: PHP粉丝网 添加日期:2018-10-19 11:13:40 浏览: 评论:0
前言:
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 //phpfensi.com
- return {job, reserved}
- LUA;
- }
为什么不用 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 也没有意义,结论就是:因为没用到阻塞的特性,或者无法保证原子性。
Tags: Laravel blpop
相关文章
- ·Laravel4创建一个占位图片服务例子(2014-06-18)
- ·深入解析Laravel5.5中的包自动发现Package Auto Discovery(2018-09-13)
- ·Laravel学习教程之request validation的编写(2018-09-13)
- ·Laravel框架实现利用中间件进行操作日志记录功能(2018-09-14)
- ·Laravel 集成的 Monolog 库对日志进行配置和记录实例(2018-09-14)
- ·Laravel Elixir运行glup命令:Error in plugin ‘gulp-notify’(2018-09-15)
- ·Laravel 5 中防止 XSS 跨站攻击的例子(2018-10-17)
- ·php7跑laravel5.0报错,异常Carbon::createFromFormat()(2018-10-23)
- ·Laravel Memcached缓存驱动的配置应用实例(2018-10-30)
- ·Laravel memcached缓存对文章增删改查进行优化例子(2018-10-30)
- ·Laravel 中通过 Artisan View 扩展包创建及删除应用视图文件(2018-10-30)
- ·laravel项目利用twemproxy部署redis集群的完整步骤(2018-11-07)
- ·Laravel框架实现利用监听器进行sql语句记录功能(2018-11-07)
- ·Laravel框架模板继承操作示例(2018-11-14)
- ·Laravel框架实现定时发布任务的方法(2018-11-15)
- ·Laravel中错误与异常处理的用法示例(2018-11-18)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)