在上一篇中我们讲了一个最简单的 yii2-queue 队列扩展的例子, 接下来的日子里阿北将带你一起深入到这个扩展的内部, 本篇说说当我们使用 File 类型来存储队列信息时候的相关事情
File 类型队列由一个 index.data 和一堆任务文件构成
当我们推送一个任务到队列的时候, 这个任务会生成一个文件, 名字命名如下 jobXXX.data,XXX 是任务编号, 具体编号是多少从一个叫做 index.data 的文件中获取
因为队列时刻在变化, 因此这些文件默认情况下存放到了 yii2 程序的 runtime/queue 下, 当然我们可以通过如下配置来修改这个路径
- // config/web.php
- return ['components' => [
- 'queue' => [
- 'class' => \yii\queue\file\Queue::class,
- 'path' => '@runtime/queue',
- ],
- ],
- ];
现在我们来看一下流程
push
当我们执行任务推送的时候, 在 runtime/queue 文件夹下会生成一个文件
Snipaste_2018-02-08_06-52-56.png
在这里有两个问题要研究
job 的内容是什么?
job102 中的 102 是如何来的?
首先我们知道在 yii2-queue 中每个任务被抽象成一个类的对象, 比如上节课中我们的模板发送类
- namespace app\queue;
- ...
- class TemplateJob extends Component implements \yii\queue\JobInterface {
- /**
- * 订阅会员 ID
- * @var
- */
- public $userId;
- .....
- public function execute($queue){
- }
- }
每个任务就是一个类的对象, 它自然包含自己的相关属性, 因此每个 jobXXX.data 里包含的是这个任务所属那个类以及自身的属性值, 我们来深入看一个任务文件的内容
O:21:"app\queue\TemplateJob":6:{s:6:"userId";i:101;s:6:"openId";N;s:6:"itemId";N;s:11:"subscribeId";N;s:27:"yii\base\Component_events";a:0:{}s:30:"yii\base\Component_behaviors";N;}
这是一个被序列化以后的内容, 但是从里面仍然可以分析出, 这个任务隶属于 TemplateJob 类, 有 userIdopenIditemID 和 subscribeId 四个属性并且已经赋值
接下来我们来看看任务文件的编号是如何获取的
那必然要看看 index.data 文件了
a:4:{s:6:"lastId";i:138;s:7:"waiting";a:0:{}s:7:"delayed";a:0:{}s:8:"reserved";a:0:{}}
这里面包含了最近的一个任务编号, 如果系统又 push 了一个任务, 则从 lastId+1(138+1=139), 然后 lastId 被设置成 139 再, 同时该文件中含有当前队列的情况, 比如 waiting 表示当前多少个任务等待执行 delayed 表示有多少个延迟的任务
因为 index.data 的存在, 当我们在命令行执行 queue/info 命令的时候才会看到如下结果
Snipaste_2018-02-08_07-08-44.png
现在你明白了吧
执行任务
yii2-queue 可以通过命令行来执行队列中的每个任务, 如下图
Snipaste_2018-02-08_07-44-54.png
当执行成功一个任务后会删除对应文件同时更新 index.data 文件, 而整个执行任务的是由 yii2-queue 库的 /drivers/file/Command.php 类来执行, 除了 listen 和 run 外, 还有比如 inforemoveclear 方法, 关于命令行 action 的讲解我们会放到一个单独篇章进行介绍
关于数据的处理
在上面我们说了在. data 文件中, 数据是序列化的结果当然你可以改变它, 虽然不推荐
改配置文件
- // config/web.php
- return [
- 'components' => [
- 'queue' => [
- 'class' => \yii\queue\file\Queue::class,
- 'path' => '@runtime/queue',
- 'indexSerializer'=>'ser',
- 'indexDeserializer'=>'unser'
- ],
- ],
- ];
我们可以通过 indexSerializer 和 indexDeserializer 指定对 data 文件数据的加密和解密过程, 当然如果真这样我们还要定义 ser 和 unser 方法来处理具体逻辑, 那就需要我们自己定义一个 file 类型的队列类, 它继承于 \ yii\queue\file\Queue 并实现 ser 和 unser 方法才可以
来源: http://www.jianshu.com/p/287350626bd6