众所周知,PHP要实现异步任务通常都是经过 Gearman
Beanstalkd
等第三方来实现的。目前项目采用的是 Gearman
来实现异步任务。php
通俗的来讲segmentfault
Gearman是一个分发任务的程序框架,使用Gearman的应用一般有三部分组成:一个Client、一个Worker、一个 任务服务器。 Client的做用是提出一个 Job 任务 交给 Job Server 任务服务器。Job Server 会去寻找一个 合适的 Worker 来完成这项任务。api
Gearman官方网站地址 Gearman官网服务器
关于Gearman 安装和使用 请参考 Gearman安装和使用框架
Gearman
请求过程当中 涉及的三个 Client -> Job -> Worker
。异步
Client 请求的发起者,能够是C,PHP,Perl,MySQL UDF等等。 Job:请求的调度者,用来负责协调把Client发出的请求转发给合适的Work。 Worker:请求的处理者,能够是C,PHP,Perl等等。
在这个过程当中 work
要长驻后台时刻准备着被jobserver
调用来处理job
,因此worker
不能死掉函数
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
的编写。this
由于 work
须要长驻后台运行,因此咱们要声明文件以 CLI
模式运行。即:spa
方式一:
<?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