天天看點

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——分布式任務分發架構

通常,多語言多系統之間的內建是個大問題,一般來說,人們多半會采用WebService的方式來處理此類內建問題,但不管采用何種風格的WebService,如RPC風格,或者REST風格,其本身都有一定的複雜性。相比之下,Gearman也能實作類似的作用,而且更簡單易用。

一個Gearman請求的處理過程涉及三個角色:Client -> Job -> Worker。

Client:請求的發起者,可以是C,PHP,Perl,MySQL UDF等等。

Job:請求的排程者,用來負責協調把Client發出的請求轉發給合适的Work。

Worker:請求的處理者,可以是C,PHP,Perl等等。

因為Client,Worker并不限制用一樣的語言,是以有利于多語言多系統之間的內建。

甚至我們通過增加更多的Worker,可以很友善的實作應用程式的分布式負載均衡架構。

3 Gearman下載下傳

    1)官網

http://gearman.org/

    2)官網下載下傳

https://launchpad.net/gearmand

    3)官網使用向導

http://gearman.org/getting-started/

    3)本次安裝用到的所有軟體下載下傳位址(安裝環境為CentOS-6.5)    

http://download.csdn.net/detail/clevercode/8698699 4 Gearman安裝 4.1 安裝linux必備常用庫

    Linux中必備常用支援庫的安裝:

http://blog.csdn.net/clevercode/article/details/45438401 4.2 安裝gearmand依賴的庫

    # yum install -y boost-devel gperf libevent-devel libuuid-devel

4.3 安裝gearmand服務

    1)解壓

    # cd /usr/local/src/gearman

    # tar xzf gearmand-1.1.12.tar.gz

    2)配置

    # cd gearmand-1.1.12

    # ./configure

    3)編譯

    # make

    4)安裝

    # make install

    5)安裝成功圖,輸入

    # gearman

5 安裝php擴充

    1)安裝phpize

    # yum install -y php-devel

    2)解壓

    # tar xzf gearman-1.1.2.tgz 

    3)配置

    # cd gearman-1.1.2

    # phpize

    4)編譯

    5)安裝

    # make install   

    6)安裝成功

出現“Installing shared extensions:     /usr/lib64/

PHP

/modules/”表示安裝成功,/usr/lib64/php/modules/是gearman.so擴充的目錄。如圖

    7)配置(加入擴充)

    # vi /usr/local/php5/etc/php.ini

    extension="gearman.so"

    8)查配置是否成功

    # vi test.php

    print gearman_version() . "\n";

    ?>

    執行php test.php後,出現1.1.12表示安裝成功

    # php test.php

    1.1.12 

6 Gearman啟動停止

    1) 建立日志/data0/logs/gearmand.log

    # touch /data0/logs/gearmand.log

    2)啟動

    # /usr/local/sbin/gearmand -d -u root -L 192.168.142.130 --log-file=/data0/logs/gearmand.log

    3)參數詳解

    -b,--backlog= 儲備的監聽連接配接數量

    -d, --daemon 背景運作

    -f, --file-descriptors= 檔案描述符的數量

    -h, --help 幫助

    -j, --job-retries= 在ob server移除不可用job之前運作的次數,防止不斷運作導緻其他可用worker崩潰。預設沒有限制

    -l, -log-file= 日志檔案存放位置(預設記錄最簡單日志)

    -L, --listen= 監聽的IP,預設全部接受

    -p, --port= 指定監聽端口

    -P, --pid-file= 指定程序ID寫入位置

    -r, --protocol= 加載協定子產品

    -q, --queue-type= 指定持久化隊列

    -t, --threads= 使用的I/9線程數量。預設為0

    -u, --user= 啟動後,切換到指定使用者

    -v, --verbose 增加一級詳細程度

    -V, --version 顯示版本資訊

    4)查是否運作

    # ps axu | grep gearmand

    5)檢視監聽端口

    # netstat -anp | grep 4730

    6)停止,直接kill掉程序。

7 Gearman使用 7.1 建立Worker

   建立worker.php,建立一個發送郵件的Worker端。代碼如下

[php] view plain copy

$worker= new GearmanWorker();  

$worker->addServer('192.168.142.130', '4730');  

$worker->addFunction("sendMail", "my_sendmail_function");  

while ($worker->work());  

function my_sendmail_function($job){  

// 接收資料  

$tmp = $job->workload();  

$receiveArr = unserialize($tmp);  

$from = $receiveArr['from'];  

$to = $receiveArr['to'];  

$subject = $receiveArr['subject'];  

$content = $receiveArr['content'];  

//發送郵件  

//....  

return $subject.' sendmail OK';  

}  

?>  

7.2 啟動Worker端

  如果處理的資料量大,可以執行以下腳本多次,即啟動多個Worker端。

   # nohup php worker.php > tmp.txt &

7.3 建立Client(阻塞模式,需要等待傳回結果才結束)

   建立一個client.php。do()方法是阻塞模式,必須等待worker端傳回結果,程式才能停止。(如圖傳回:hello Gearman sendmail OK)

$client= new GearmanClient();  

$client->addServer('192.168.142.130', '4730');  

$job = array();  

$job['from'] = 'Code';  

$job['to'] = 'Gearman';  

$job['subject'] = 'hello Gearman';  

$job['content'] = 'hello Gearman:this is from GearmanClient';  

$job = serialize($job);  

//等到worker端傳回結果,才會結束。  

$ret = $client->do("sendMail", $job);  

echo $ret."\r\n";  

7.4 建立Client(非阻塞,不用等結果)

   建立一個client2.php。doBackground()不用等待worker端傳回結果,程式就結束了。

//不等待傳回結果,就會結束  

$ret = $client->doBackground("sendMail", $job);  

8 Gearman管理

  輸入以下指令,檢視4730端口情況。

  #  (echo "status" ; sleep 2 ) | telnet 192.168.142.130 4730

  1)字段說明:"已知注冊的任務"  "正在運作的任務"  "隊列中的任務"  "可用的 Worker".

  2)sendMail        0       0       1,注冊的任務名為 sendMail,0 個正常在運作,隊列為空,有一個可用的 Worker.