PHP並發多進程處理利器Gearman使用介紹,利器gearman
工作中我們有時候會遇到比如需要同時發布資料到多個個伺服器上,或者同時處理多個任務。可以使用PHP的curl_multi的方式並發處理請求,但是由於網路和資料以及各個伺服器等等的一些情況導致這種並發處理的回應時間很慢,因為在並發請求的過程中還包括記錄日誌,處理資料等邏輯,等待處理結果並返回,所以也不能友好的滿足後台操作的體驗。
現在有另外一種方案,利Gearman來實現並發的需求。通過Client將請求發送到Gearman的Jobs,在每個Work中來再來進行curl_multi和資料處理和日誌等一些操作,同時用supervisor 來監控Gearman以及Works的進程,這樣可以實現一個並行的多進程和負載平衡的方案。
Gearman可以做什麼:
非同步處理:圖片處理,訂單處理,批量郵件/通知之類的
要求高CPU或記憶體的處理:大容量的資料處理,MapReduce運算,日誌聚集,視頻編碼
分布式和並行的處理
定時處理:累加式更新,資料複製
限制速率的FIFO處理
分布式的系統監控任務
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 串連來進行的。
Gearman可以將工作的負載分擔到不同的機器中。
安裝:
複製代碼 代碼如下:
rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noarch.rpm
yum install -y gearmand
啟動:
gearmand -d
安裝PHP Gearman擴充
我都是用pcel來安裝的,你也可以下載源碼包來編譯安裝,但是記得要先安裝libgearman和re2c,不然擴充編譯安裝會出錯。
pecl install gearman #不成功並提示版本問題可以試試 pecl install gearman-1.0.3,預設好像是1.1.2
編譯安裝也很簡單
複製代碼 代碼如下:
wget -c http://pecl.php.net/get/gearman-1.1.1.tgz
tar zxvf gearman-1.1.1.tgz
phpize
./configure
make && make install
echo "extension=gearman.so" >> /etc/php.ini
PHP介面函數
Gearman提供很多完善的擴充函數,包括GearmanClient,GearmanJob,GearmanTask,GearmanWorker,具體可以查看PHP官方手冊.
這是官方提供的Example其中的一個,相當與一個並發的分發任務處理的例子
<?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);
gearman_work.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());
我在3個終端中都執行了gearman_work.php
ryan@ryan-lamp:~$ ps aux | grep gearman* | grep -v grepgearman 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.1ryan 2992 0.0 0.8 43340 9036 pts/0 S+ 14:05 0:00 php /var/www/gearmand_work.phpryan 3713 0.0 0.8 43340 9036 pts/1 S+ 14:05 0:00 php /var/www/gearmand_work.phpryan 3715 0.0 0.8 43340 9036 pts/2 S+ 14:05 0:00 php /var/www/gearmand_work.php
來查看下執行gearman_work.php的結果shell
複製代碼 代碼如下:
Fetching...
Got user info in: 3.03 seconds:
string(59) "The user requested (joe@joe.com) is 7 feet tall and awesome"
string(56) "The user (joe@joe.com) is 1 degree away from Kevin Bacon"
string(43) "The user (joe@joe.com) has no posts, sorry!"
看到上面的3.03 seconds,說明client請求過去的任務被並行分發執行了。
在實際的生產環境中,為了監測gearmand和work的進程沒有被意外退出,我們可以藉助Supervisor這個工具.
http://www.bkjia.com/PHPjc/1127877.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1127877.htmlTechArticlePHP並發多進程處理利器Gearman使用介紹,利器gearman 工作中我們有時候會遇到比如需要同時發布資料到多個個伺服器上,或者同時處理多個任...