衆所周知,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