《PHP實例:PHP并發多進程處理利器Gearman使用介紹》要點:
本文介紹了PHP實例:PHP并發多進程處理利器Gearman使用介紹,希望對您有用。如果有疑問,可以聯系我們。
PHP學習工作中我們有時候會遇到比如需要同時發布數據到多個個服務器上,或者同時處理多個任務.可以使用PHP的curl_multi的方式并發處理哀求,但是由于網絡和數據以及各個服務器等等的一些情況導致這種并發處理的響應時間很慢,因為在并發哀求的過程中還包括記錄日志,處理數據等邏輯,等待處理結果并返回,所以也不能友好的滿足后臺操作的體驗.
PHP學習現在有另外一種方案,利Gearman來實現并發的需求.通過Client將哀求發送到Gearman的Jobs,在每個Work中來再來進行curl_multi和數據處理和日志等一些操作,同時用supervisor 來監控Gearman以及Works的進程,這樣可以實現一個并行的多進程和負載均衡的方案.
PHP學習Gearman可以做什么:
PHP學習異步處理:圖片處理,訂單處理,批量郵件/通知之類的
要求高CPU或內存的處理:大容量的數據處理,MapReduce運算,日志聚集,視頻編碼
分布式和并行的處理
定時處理:增量更新,數據復制
限制速率的FIFO處理
分布式的系統監控任務
PHP學習Gearman工作原理:
使用Gearman的應用通常有三部分組成:一個Client、一個Worker、一個 任務服務器. Client的作用是提出一個 Job 任務 交給 Job Server 任務服務器.Job Server 會去尋找一個 合適的 Worker 來完成這項任務.Worker 執行由 Client 發送過來的 Job,并且將結果通過 Job Server 返回給 Client.Gearman 提供了 Client 和 Worker 的 API,利用這些API 應用可以同 Gearman Job Server來進行通信.Gearman 內部 Client 和 Worker 之間的通信都是通過 TCP 連接來進行的.
PHP學習
PHP學習Gearman可以將工作的負載分擔到不同的機器中.
PHP學習
PHP學習安裝:
PHP學習啟動:
gearmand -d
PHP學習安裝PHP Gearman擴展
我都是用pcel來安裝的,你也可以下載源碼包來編譯安裝,但是記得要先安裝libgearman和re2c,不然擴展編譯安裝會出錯.
PHP學習pecl install gearman #不成功并提示版本問題可以試試 pecl install gearman-1.0.3,默認好像是1.1.2
編譯安裝也很簡單
PHP學習PHP接口函數
Gearman提供很多完善的擴展函數,包括GearmanClient,GearmanJob,GearmanTask,GearmanWorker,具體可以查看PHP官方手冊.
這是官方提供的Example其中的一個,相當與一個并發的分發任務處理的例子
PHP學習
<?php
$client = new GearmanClient();
$client->addServer();
// initialize the results of our 3 "query results" here
$userInfo = $friends = $posts = null;
// This sets up what gearman will callback to as tasks are returned to us.
// The $context helps us know which function is being returned so we can
// handle it correctly.
$client->setCompleteCallback(function(GearmanTask $task, $context) use (&$userInfo, &$friends, &$posts) {
switch ($context)
{
case 'lookup_user':
$userInfo = $task->data();
break;
case 'baconate':
$friends = $task->data();
break;
case 'get_latest_posts_by':
$posts = $task->data();
break;
}
});
// Here we queue up multiple tasks to be execute in *as much* parallelism as gearmand can give us
$client->addTask('lookup_user', 'joe@joe.com', 'lookup_user');
$client->addTask('baconate', 'joe@joe.com', 'baconate');
$client->addTask('get_latest_posts_by', 'joe@joe.com', 'get_latest_posts_by');
echo "Fetching...\n";
$start = microtime(true);
$client->runTasks();
$totaltime = number_format(microtime(true) - $start, 2);
echo "Got user info in: $totaltime seconds:\n";
var_dump($userInfo, $friends, $posts);
PHP學習gearman_work.php
PHP學習
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('lookup_user', function(GearmanJob $job) {
// normally you'd so some very safe type checking and query binding to a database here.
// ...and we're gonna fake that.
sleep(3);
return 'The user requested (' . $job->workload() . ') is 7 feet tall and awesome';
});
$worker->addFunction('baconate', function(GearmanJob $job) {
sleep(3);
return 'The user (' . $job->workload() . ') is 1 degree away from Kevin Bacon';
});
$worker->addFunction('get_latest_posts_by', function(GearmanJob $job) {
sleep(3);
return 'The user (' . $job->workload() . ') has no posts, sorry!';
});
while ($worker->work());
PHP學習我在3個終端中都執行了gearman_work.php
PHP學習
ryan@ryan-lamp:~$ ps aux | grep gearman* | grep -v grep
gearman 1504 0.0 0.1 60536 1264 ? Ssl 11:06 0:00 /usr/sbin/gearmand --pid-file=/var/run/gearman/gearmand.pid --user=gearman --daemon --log-file=/var/log/gearman-job-server/gearman.log --listen=127.0.0.1
ryan 2992 0.0 0.8 43340 9036 pts/0 S+ 14:05 0:00 php /var/www/gearmand_work.php
ryan 3713 0.0 0.8 43340 9036 pts/1 S+ 14:05 0:00 php /var/www/gearmand_work.php
ryan 3715 0.0 0.8 43340 9036 pts/2 S+ 14:05 0:00 php /var/www/gearmand_work.php
PHP學習來查看下執行gearman_work.php的結果shell
PHP學習看到上面的3.03 seconds,說明client哀求過去的任務被并行分發執行了.
在實際的生產環境中,為了監測gearmand和work的進程沒有被意外退出,我們可以借助Supervisor這個工具.