4

众所周知,PHP要实现异步任务一般都是通过 Gearman Beanstalkd 等第三方来实现的。目前项目采用的是 Gearman 来实现异步任务。

关于Gearman介绍

通俗的来说

Gearman是一个分发任务的程序框架,使用Gearman的应用通常有三部分组成:一个Client、一个Worker、一个 任务服务器。 Client的作用是提出一个 Job 任务 交给 Job Server 任务服务器。Job Server 会去寻找一个 合适的 Worker 来完成这项任务。

Gearman官方网站地址 Gearman官网

关于Gearman 安装和使用 请参考 Gearman安装和使用

PHP使用Gearman

Gearman 请求过程中 涉及的三个 Client -> Job -> Worker

Client 请求的发起者,可以是C,PHP,Perl,MySQL UDF等等。

Job:请求的调度者,用来负责协调把Client发出的请求转发给合适的Work。

Worker:请求的处理者,可以是C,PHP,Perl等等。

在这个过程中 work要长驻后台时刻准备着被jobserver调用来处理job,所以worker不能死掉

PHP使用Gream实例(单独函数实现)

client.php
<?php
    $client= new GearmanClient();
    $client->addServer('127.0.0.1', 4730);
    $client->doBackground('say','hello world');
work.php
<?php
    $worker= new GearmanWorker();
    $worker->addServer("127.0.0.1", 4730);
     $worker->addFunction("say", "hello");
     while ($worker->work());
     function hello () {
         //DO SOMETHING...
     }

以上即是 PHP 调用 Gearman 简单的示例。

在我们实际的开发过程中,一般会采用框架进行项目的开发,如果采用以上方式进行调用,肯定会破坏项目原有的文件结构。 以下以ThinkPHP 3.2 版本进行DEMO演示,调用方式跟单文件调用没什么区别,区别在于 work的编写。

因为 work需要长驻后台运行,所以我们要声明文件以 CLI 模式运行。即:

方式一:

<?php
    namespace Sys\Controller;
    use Think\Controller;
    class DemoController extends Controller {
        protected $_config = array(
            'host' => 'XXXX',
            'port' => 'XXX'
        );
        public function __construct () {
            $sapi = php_sapi_name();
            if ($sapi != 'cli') {
                exit();
            }
        }
        
        protected function add_work ($job,$func) {
            $worker= new GearmanWorker();
            $worker->addServer($this->$_config['host'], $this->$_config['port']);
            $worker->addFunction($job, $func);
            while ($worker->work());
        }
        
        public function test () {
            $this->add_work('say','\Sys\Controller\DemoController ::say');
        }
        
        static public function say ($job) {
            $data = $job->workload();
            //DO SOMETHING...
        }
    }
    

方式二:

<?php
    namespace Sys\Controller;
    use Think\Controller;
    class DemoController extends Controller {
        protected $_config = array(
            'host' => 'XXXX',
            'port' => 'XXX'
        );
        public function __construct () {
            $sapi = php_sapi_name();
            if ($sapi != 'cli') {
                exit();
            }
        }
        
        protected function add_work ($job,$func) {
            $worker= new GearmanWorker();
            $worker->addServer($this->$_config['host'], $this->$_config['port']);
            $worker->addFunction($job, $func);
            while ($worker->work());
        }
        
        public function test () {
            $this->add_work('say','\Sys\Controller\say');
        }
    }
    
    function say ($job) {
        $data = $job->workload();
        //DO SOMETHING.....
    }

添加work到后台 格式为 /var/www/index.php Sys/Demo/test


Oooooooo
1.7k 声望69 粉丝