美文网首页
关于yii 框架使用queue 的 delay一点心得

关于yii 框架使用queue 的 delay一点心得

作者: 句小芒 | 来源:发表于2019-07-06 11:47 被阅读0次

在使用queue队列的时候,发现会传入一个delay参数,表示延时执行。那么就要思考一个问题:a先入队列,delay比较长,b后入队列,delay较短。那么会发生什么情况呢?

按照队列先进先出的原则,即使b的延时执行时间较长,也应该等到它之前的先出队列,这样的话,会造成队列阻塞。这显然不是我们想要的。

为了验证以上情况,特意测试了一下。
下面是一个邮件发送的请求。

CQueue::push(EmailSendJob::class, [
            'sender'  => ['发送方@email.com' => '数据报表'],
            'email'   => '接收方@email.com',
            'subject' => ' 邮件主题',
            'content' => "发送时间" . $rand,
        ], ['delay' => $rand]);

第一次执行时,rand = 5 , 第二次执行rand = 3; 看一下谁会先发送。

结果 : 先收到第二次执行的邮件。
结论 :delay时间短的先执行。我们可能会疑惑,这明显不符合队列的原则。

接下来,我们去探索一下为什么会发生这种情况,底层到底是怎么去实现的。
分析:

首先看一下配置文件中的

  $baseConfig  = [
    'class'         => '\yii\queue\redis\Queue',
    // 'on afterPush'  => ['\common\queue\ExecEventHandler', 'afterPush'],
    // 'on beforeExec' => ['\common\queue\ExecEventHandler', 'beforeExec'],
    // 'on afterExec'  => ['\common\queue\ExecEventHandler', 'afterExec'],
    'on afterError' => ['\common\queue\ExecEventHandler', 'afterError'],
    'redis'         => [
        'class'    => 'yii\redis\Connection',   //驱动程序使用Redis存储队列数据,也可能会使用MemCache或其他的来存储。
        'hostname' => 'redis_Ip',       //redis的ip地址
        //有密码的话也要加进去
        'port'     => 6379,   //端口号
        'database' => 0,   //使用哪个数据库
    ],
];

我们现在知道了,他是使用Redis来存储队列数据,那么我们在执行时看一下redis会产生什么数据。
首先,我们选择一个新库,这里我选择db1。里面刚开始是没有数据的。
然后上面代码的database 改为1 ,delay设置为120(秒),运行。。。。。。

console 下脚本运行的命令 php yii 控制器名/方法名

屏幕快照 2019-07-06 上午10.36.01.png

我们可以看到,redis生成了三个数据, 分别是log_queue.delayed,log_queue.message_id,log_queue.messages。
我们看一下他们的数据类型和内容。

delayed.png message_id_.png messages.png

首先,他们是zset(集合的形式存储的)。
第一张表:存储的是delay的数据,score 表示其过期时间,那value 列是什么数据呢?
因为redis集合具有唯一性,但是有可能delay的值是相同的,所以加了一个字段。并且数据还可以排序。

第二张表:存储的是最后一次成功后返回的value值。

第三张表:存储数据,所有内容数据都存储在value字段中。

分析完毕。

相关文章

网友评论

      本文标题:关于yii 框架使用queue 的 delay一点心得

      本文链接:https://www.haomeiwen.com/subject/bhauhctx.html