众所周知,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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。