PHP并發(fā)多進(jìn)程處理利器Gearman使用介紹
工作中我們有時(shí)候會(huì)遇到比如需要同時(shí)發(fā)布數(shù)據(jù)到多個(gè)個(gè)服務(wù)器上,或者同時(shí)處理多個(gè)任務(wù)??梢允褂肞HP的curl_multi的方式并發(fā)處理請(qǐng)求,但是由于網(wǎng)絡(luò)和數(shù)據(jù)以及各個(gè)服務(wù)器等等的一些情況導(dǎo)致這種并發(fā)處理的響應(yīng)時(shí)間很慢,因?yàn)樵诓l(fā)請(qǐng)求的過(guò)程中還包括記錄日志,處理數(shù)據(jù)等邏輯,等待處理結(jié)果并返回,所以也不能友好的滿足后臺(tái)操作的體驗(yàn)。
現(xiàn)在有另外一種方案,利Gearman來(lái)實(shí)現(xiàn)并發(fā)的需求。通過(guò)Client將請(qǐng)求發(fā)送到Gearman的Jobs,在每個(gè)Work中來(lái)再來(lái)進(jìn)行curl_multi和數(shù)據(jù)處理和日志等一些操作,同時(shí)用supervisor 來(lái)監(jiān)控Gearman以及Works的進(jìn)程,這樣可以實(shí)現(xiàn)一個(gè)并行的多進(jìn)程和負(fù)載均衡的方案。
Gearman可以做什么:
異步處理:圖片處理,訂單處理,批量郵件/通知之類的
要求高CPU或內(nèi)存的處理:大容量的數(shù)據(jù)處理,MapReduce運(yùn)算,日志聚集,視頻編碼
分布式和并行的處理
定時(shí)處理:增量更新,數(shù)據(jù)復(fù)制
限制速率的FIFO處理
分布式的系統(tǒng)監(jiān)控任務(wù)
Gearman工作原理:
使用Gearman的應(yīng)用通常有三部分組成:一個(gè)Client、一個(gè)Worker、一個(gè) 任務(wù)服務(wù)器。 Client的作用是提出一個(gè) Job 任務(wù) 交給 Job Server 任務(wù)服務(wù)器。Job Server 會(huì)去尋找一個(gè) 合適的 Worker 來(lái)完成這項(xiàng)任務(wù)。Worker 執(zhí)行由 Client 發(fā)送過(guò)來(lái)的 Job,并且將結(jié)果通過(guò) Job Server 返回給 Client。Gearman 提供了 Client 和 Worker 的 API,利用這些API 應(yīng)用可以同 Gearman Job Server來(lái)進(jìn)行通信。Gearman 內(nèi)部 Client 和 Worker 之間的通信都是通過(guò) TCP 連接來(lái)進(jìn)行的。
Gearman可以將工作的負(fù)載分擔(dān)到不同的機(jī)器中。
安裝:
rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/epel-release-6-5.noarch.rpm
yum install -y gearmand
啟動(dòng):
gearmand -d
安裝PHP Gearman擴(kuò)展
我都是用pcel來(lái)安裝的,你也可以下載源碼包來(lái)編譯安裝,但是記得要先安裝libgearman和re2c,不然擴(kuò)展編譯安裝會(huì)出錯(cuò)。
pecl install gearman #不成功并提示版本問(wèn)題可以試試 pecl install gearman-1.0.3,默認(rèn)好像是1.1.2
編譯安裝也很簡(jiǎn)單
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接口函數(shù)
Gearman提供很多完善的擴(kuò)展函數(shù),包括GearmanClient,GearmanJob,GearmanTask,GearmanWorker,具體可以查看PHP官方手冊(cè).
這是官方提供的Example其中的一個(gè),相當(dāng)與一個(gè)并發(fā)的分發(fā)任務(wù)處理的例子
<?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個(gè)終端中都執(zhí)行了gearman_work.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
來(lái)查看下執(zhí)行g(shù)earman_work.php的結(jié)果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,說(shuō)明client請(qǐng)求過(guò)去的任務(wù)被并行分發(fā)執(zhí)行了。
在實(shí)際的生產(chǎn)環(huán)境中,為了監(jiān)測(cè)gearmand和work的進(jìn)程沒(méi)有被意外退出,我們可以借助Supervisor這個(gè)工具.
- php使用gearman進(jìn)行任務(wù)分發(fā)操作實(shí)例詳解
- python基于json文件實(shí)現(xiàn)的gearman任務(wù)自動(dòng)重啟代碼實(shí)例
- gearman中worker常駐后臺(tái),導(dǎo)致MySQL server has gone away的解決方法
- PHP使用gearman進(jìn)行異步的郵件或短信發(fā)送操作詳解
- gearman + mysql方式實(shí)現(xiàn)持久化操作示例
- gearman管理工具GearmanManager的安裝與php使用方法示例
- Gearman::XS在Centos下的編譯安裝方法
- gearman隊(duì)列持久化引發(fā)的問(wèn)題及解決方法
- gearman的安裝啟動(dòng)及python API使用實(shí)例
- rhel5.7下安裝gearmand及啟動(dòng)的方法
- gearman中任務(wù)的優(yōu)先級(jí)和返回狀態(tài)實(shí)例分析
相關(guān)文章
PHP連續(xù)簽到功能實(shí)現(xiàn)方法詳解
這篇文章主要介紹了PHP連續(xù)簽到功能實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了PHP結(jié)合mysql數(shù)據(jù)庫(kù)實(shí)現(xiàn)連續(xù)簽到功能相關(guān)操作技巧,需要的朋友可以參考下2019-12-12php實(shí)現(xiàn)的簡(jiǎn)單日志寫入函數(shù)
這篇文章主要介紹了php實(shí)現(xiàn)的簡(jiǎn)單日志寫入函數(shù),涉及針對(duì)文件的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03使用Xdebug調(diào)試和優(yōu)化PHP程序之[1]
使用Xdebug調(diào)試和優(yōu)化PHP程序之[1]...2007-04-04PHP set_time_limit(0)長(zhǎng)連接的實(shí)現(xiàn)分析
每次我們?cè)L問(wèn)PHP腳本的時(shí)候,都是當(dāng)所有的PHP腳本執(zhí)行完成后,我們才得到返回結(jié)果。如果我們需要一個(gè)腳本持續(xù)的運(yùn)行,那么我們就要通過(guò)php長(zhǎng)連接的方式,來(lái)達(dá)到運(yùn)行目的。2010-03-03PHP圖像處理 imagestring添加圖片水印與文字水印操作示例
這篇文章主要介紹了PHP圖像處理 imagestring添加圖片水印與文字水印操作,結(jié)合實(shí)例形式分析了PHP使用imagestring添加圖片水印與文字水印具體操作步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2020-02-02php組合排序簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要介紹了php組合排序簡(jiǎn)單實(shí)現(xiàn)方法,涉及php數(shù)據(jù)結(jié)構(gòu)與數(shù)學(xué)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2016-10-10Linux系統(tǒng)中為php添加pcntl擴(kuò)展
上篇文章我們介紹了在mac系統(tǒng)中為片php添加pcntl擴(kuò)展插件,本文我們繼續(xù)來(lái)分享下Linux系統(tǒng)中為php添加pcntl擴(kuò)展的方法,希望小伙伴們能夠喜歡2016-08-08php 數(shù)據(jù)庫(kù)字段復(fù)用的基本原理與示例
php 數(shù)據(jù)庫(kù)字段復(fù)用的基本原理與示例,需要的朋友可以參考下。2011-07-07