Loong 2018-03-08 10:22:27 5418次浏览 6条评论 0 0 0

== 关于队列 ==

1.队列就像是一个容器,把来不及操作的东西井然有序的放入。

2.通俗的讲,可以把队列看做一个城市的马路。有很多马路,各有各的秩序和走向,先驶入的先走出马路,马路与马路车辆不会相互影响。队列里的内容是有一定规格的,就想机动车和非机动车一样,相同规格的在相同的路上行进。

3.队列就像线性表一样,两头都可以操作,但是表头只出表尾只进,表中的内容只是进行存储。

这样看难点就在于,表存在什么地方,在表中的数据什么时候取出,操作失败之后要怎么办等。于是这个时候就需要驱动,扩展,插件等来辅助了。

== 关于 yii2-queue YII原生福利 ==

1,安装

利用composer快速安装 . php composer.phar require --prefer-dist yiisoft/yii2-queue

2,配置

在config中添加配置‘queue’的信息。由于这个yii原生的队列可以支持多种驱动,所以在配置前还是要先选好驱动。

参考:https://github.com/yiisoft/yii2-queue/tree/master/docs/guide-zh-CN

测试实例:示例是console的config/main.php中配置方式 queue在console的config/main.php中配置方式 1.File

这里的第一个queue是file驱动型。是把放入队列的数据加密存储成一个个文件(可能会被规则命名为job1.data的形式)。这里要注意path。由于YII的每个项目中存在多个APP,配置文件可以相互独立,队列在项目前端APP中进行添加,所以需要在该APP配置队相同的内容,但是要注意一点,这里的path需要指到相同的位置。

2.Redis

第三个是redis驱动,这里要注意的是redis是要另外配置,可以在common的APP中config/main-local.php。配置方式类似下图: redis-queue

另外DB形式和redis类似,配置好db部分和queue部分(redis也可以看做是非关系型数据库的一种,这里对数据存储处理几乎一致)

3.Beanstalk

作为主流驱动兔子比较受欢迎,但是兔子系列的基本都是比较大型的,一般小项目PHP选用beanstalk也比较多。(而且就个人原因手上的旧项目选用的也是这个,在使用和表述上有据可考也是极好)所以我原则beanstalk进行深入表述

beanstalk是可以在其他框架下仍然好用的软件,这里我要从三种不同的方式操作。首先就是今天的主题,利用YII2-queue,其二是用udokmeci\yii2beanstalk,第三就是pheanstalk。这三种都是对beanstalk进行操作,三者可以交错使用。

------ 利用yii2soft/yii2-queue ------

其中的存储类型是特殊的,我们需要先新建一个类。

` <?php

namespace forTool\modules\v1\models\common;

use Yii; //use yii\queue\JobInterface; use common\base\controllers\ExcelDeal; use yii\queue\RetryableJobInterface;

class BaseJob implements RetryableJobInterface {

public $url;//存储的json格式键名,为方便获取,会定义成属性
public $file;
public function __construct($array)
{
    $this->url = $array['url'];

    $this->file = $array['file'];

    return $this;
}

//这个函数是必须要有的因为接口的实现,这里的函数是在队列入队执行的

public function execute($queue)
{
    echo '我正在执行队列。。。';
    var_dump($this);
    file_put_contents($this->file, file_get_contents($this->url));
}

//这个是对队列任务的延迟设置

public function getTtr()
{
    echo 'ttr';
    return 15 * 60;
}

//设置任务的延迟重复

public function canRetry($attempt, $error)
{
    echo 'can try';
    return ($attempt < 5) && ($error );
}

}`

我的这个类叫BaseJob,所以之后的队列如果利用yii2-queue进行封装入队时就需要用这里类作为存储。

例如在需要入队的时候: ` $id_11 = Yii::$app->queue->push(new BaseJob([

        'url' => 'http://img3.imgtn.bdimg.com/it/u=1243131531,3821032402&fm=27&gp=0.jpg',
        'file' => '../runtime/tmp/image.jpg',
    ]));`

当然数据结构是根据个人而定,这里是可以完成图片下载的逻辑,入队的是图片下载地址和将下载存储的地址。队列中数据的处理则写在execute()中

那么问题出来了,数据在什么时候才能出队?什么时候才能执行?和其他驱动类似,我们可以用:php yii queue/listen

来监听队列,如果非延迟任务入队将直接执行相应的exectue。延迟任务则在相应时间之后执行。另外还可以使用:php yii queue/info 来检查队列状态。php yii remove [id] 来移除指定的ID任务。等等命令,这些都是通过在console配置直接执行的。队列情况实例如下:

终端图片

== 关于 beanstalk ==

在正式开始之前就涉及到一个关于提供服务问题,在上一个模块的最后提到了关于beanstalk.这里出现一个问题,我的实例代码是按照本机是提供服务配置的,显然这里提供服务的是本机,如果需要其他的机子就换掉IP和端口就好,但是要吧本机作为主机嘞~ 1.配置beanstalk服务主机。

(1)安装(基于MAC)

brew install beanstalk

(2)确认安装成功

执行相关帮助或查询版本的命令;例如:beanstalk -h

(3)开启服务

beanstalk -l 地址 -p 端口号

参考资料: http://blog.csdn.net/ahjxhy2010/article/details/53196450

https://segmentfault.com/a/1190000002784775

http://www.51siyuan.cn/91.html

https://getyii.com/topic/531

2.基于beanstalk的入队操作

参考:

http://blog.csdn.net/taotaobaobei/article/details/78570963

http://blog.csdn.net/taotaobaobei/article/details/78571063

很多网站上都没又说这两个的区别,方法也是混着用的,(或许在其他框架是一样的)但是YII在两种的入队方式不大相同。

(1)udokmeci\yii2beanstalk

  (a)安装  :composer require udokmeci\yii2beanstalk

  (b)使用:
  
        (i)配置

    'beanstalk'=>[
        'class' => 'udokmeci\yii2beanstalk\Beanstalk',
        'host'=> "127.0.0.1", // default host
        'port'=>11300, //default port
        'connectTimeout'=> 1,
        'sleep' => false, // or int for usleep after every job
    ],
    
       (ii)入队
       
       ` $bean = Yii::$app->beanstalk;
       $bean->putInTube('tubequeue',['unique_id' => 11, 'source' => 2, 'method'=> 'get']);`

这里入队的时候有较大区别,但在执行的时候都是一个文件

(2)pda/pheanstalk(https://github.com/pda/pheanstalk/)

  (a)安装  :composer require pda/pheanstalk

  (b)执行
       (i)配置:看起来主流的都是实例化对象进行调用,并没配置,不过可以封装一个类自动填写实例化内容
       (ii)入队。这里要注意的是,入队的内容要转成JSON格式
      这个是主流PHP中对beanstalk的操作依赖,可以有较灵活的操作,获取状态,管道名称个数,获取某个管道的状态信息等

(3)yii-queue (安装和入队和前面讲的一样。)

3.关于beanstalk的执行

利用上面提到的(1),(2)两种。数据处理的类别是要集成BeanstalkController的。例如:

` <?php

namespace console\controllers;

use yii; use udokmeci\yii2beanstalk\BeanstalkController; class JobController extends BeanstalkController

{

public $url;
public $file;
// Those are the default values you can override

const DELAY_PRIORITY = "1000"; //Default priority
const DELAY_TIME = 5; //Default delay time

// Used for Decaying. When DELAY_MAX reached job is deleted or delayed with
const DELAY_MAX = 3;

public function listenTubes(){

// return ["tube"];

    return ["tubequeue","tubePhean"];

}

public function actionTubePhean($job){
    try {

        $sentData = $job->getData();
        //相应操作
    }
    catch (\Exception $e) {
        //If there is anything to do.
        fwrite(STDERR, Console::ansiFormat($e."\n", [Console::FG_RED]));
        // you can also bury jobs to examine later
        return self::BURY;
    }
}
public function actionTubequeue($job){
    try {
        $sentData = $job->getData();
        //相应操作
    }
    catch (\Exception $e) {
        //If there is anything to do.
        fwrite(STDERR, Console::ansiFormat($e."\n", [Console::FG_RED]));
        // you can also bury jobs to examine later
        return self::BURY;
    }
}

/**
 *
 * @param Pheanstalk\Job $job
 * @return string  self::BURY
 *                 self::RELEASE
 *                 self::DELAY
 *                 self::DELETE
 *                 self::NO_ACTION
 *                 self::DECAY
 *
 */
public function actionTube($job){

// $sentData = $job->getData();

    try {
        $sentData = $job->getData();

        //相应操作

        // something useful here

        

        // if you return anything else job is burried.
    } catch (\Exception $e) {
        //If there is anything to do.
        fwrite(STDERR, Console::ansiFormat($e."\n", [Console::FG_RED]));
        // you can also bury jobs to examine later
        return self::BURY;
    }
}

} `

上面是一个简单的示例,没有对取到的数据做任何操作,只是去取出各种存入的数据。只看其中必要问题。

要点一:

对于: listenTubes()是表述监听的tube的名字。类似于php yii queue/listen的作用,会主动开启监听。

要监听多个tbue时。就要写成数组的形式。

要点二:

对于不同tbue的操作是利用不同函数区分,函数要用tube的名字命名。要注意对不同处理结果的处理

亿速云
  • 评论于 2018-03-08 10:24 举报

    第一次发,格式有点不会编辑。看起来难受的可以看下:https://my.oschina.net/jlong/blog/1631161。
    这是之前在其他网站整理出来的,格式看起来整齐一点

    1 条回复
    评论于 2018-10-23 09:40 回复

    请问以下yii2 基础版本 怎么安装queue呢,高级版本安装成功了,但是我现在项目用的是基础版本,最后没有init.bat来重置生成 在cmd下 yii后,都没有关于queue的命令

  • 评论于 2018-09-13 18:27 举报

    yii2-queue支持多个队列吗??怎么分

  • 评论于 2018-09-17 10:42 举报

    感觉用队列把问题复杂化了,个人用一个带状态标识的计划任务表来处理更简单直接

  • 评论于 2018-10-23 10:27 举报

    请问以下yii2 基础版本 怎么安装queue呢,高级版本安装成功了,但是我现在项目用的是基础版本,最后没有init.bat来重置生成 在cmd下 yii后,都没有关于queue的命令

    2 条回复
    评论于 2018-10-24 15:15 回复

    queue配置需要写在configs/console.php里

    评论于 2018-11-02 11:20 回复

    好的,谢谢,问题已经解决!

  • 评论于 2018-12-04 23:01 举报

    你好,我想问一下,如果我的并发量是1000以上,用的队列是beanstalkd,那么我应该怎么去优化这个beanstalkd,让他更好的工作。之前我听别人说是增加进程数,那应该怎么去增加?谢谢指教!

  • 评论于 2019-01-18 17:47 举报

    **

您需要登录后才可以评论。登录 | 立即注册