redis队列实现

redis队列,使用了list列表数据结构,lpush生成,rpop消费模式。

队列处理命令

yiic queue worker --qname=<queue_name>

<queue_name>是队列的名称,例如:current, position等等, 这只是消费者,即队列处理程序。

这是一个典行的yii的命令行程序,文件在/path/to/protected/commands/queueCommand.php.

调用的是actionWorker方法, yii中的命令行程序也可以看做一种MVC 上面的命令就是控制器操作。

actionWorker方法大致的工作流程如下:

  1. 取出所有可用的队列名称(列表)
  2. 将命令行给定的队列名称在列表中对比,如果存在,是继续,否则退出。
  3. 随机给定一个超时时间,防止卡死(5-20分钟)
  4. 循环读取指定的队列中的内容,进行处理

队列操作说明

队列核心基础代码,在/path/to/protected/models/Queue.php中,具体做了如下封装

  • putin($params=null, $type=null) 写入队列
  • getit($type) 从队列取出一条
  • getQueueTypeList 获得所有队列名字

putin方法的参数 $params为写入队列的内容,它是一个关联数组,大致的格式如下:

array(
    'method'=>'function_name', //指定一个方法名
    //(其实这里指定的方法,已经固定到了QueueProcess.php中的方法,
    //在消费时固定了,当然也可以不固定,可以改造。
    'params'=>array( //传给这个方法的参数,目前是将这个params数组做为一个参数传给到了上面指定的方法中。
        'name'=>'name'
        'pass'=>'pass'
    )
)

$type参数是队列的名字, (实际在redis中的真实key会在前面加上queue_ 例如:task,则真实的redis中的key是queue_task),底层真实写入redis中的数据是将上面的$params进行json_encode后的字符串存入redis中。

先看一个入队列的程序

$task=array(
    'method'=>'driver_current_pos',
    'params'=>array(
        'lng'=>1.0
         'lat'=>1.0
         'driver_id'=>'BJ0001'
     )
);

Queue::model()->putin($task,'current');

再看一个,具体消费处理时的代码,此代码在/path/to/protected/commands/queueCommand.php中的queue_run方法

  private function queue_run($task) {
                //task就是从redis中取出的数据,并已经json decode后的对象了。
                $method=$task['method'];
                $params=$task['params'];
                echo "\n".$method.':'.json_encode($params);
                try {
                        
                        $queue_process=new QueueProcess();
                        //这里使用了一个php的内置方法,进行动态调用
                        //当然也可以直接写成这样php5.5.3之后可以
                        //$queue_process->{$method}($params); 这样可能更直观
                        //php5.5.3之前,只能向下面这样写
                       
                        call_user_func_array(array(
                                        $queue_process,
                                        $method
                        ), array(
                                        $params
                        ));
                } catch(Exception $e) {
                        echo "error:$method\n";
                        print_r($e);
                }
        }

那么相对应的队列业务处理的代码,基本上就都在QueueProcess这个类中了,他的位置在/path/to/protected/models/QueueProcess.php.

posted @ 2018-10-23 14:19  温柔的风  阅读(309)  评论(0编辑  收藏  举报