Gearman的安裝和使用

首發於 樊浩柏科學院

Gearman 是一個分佈式任務分發系統,經過程序調用(API,跨語言)分佈式地把工做委派給更適合作某項工做的機器,且這些機器能夠以併發的、負載均衡的形式來共同完成某項工做。當計算密集型場景時,適合在後臺使用 Gearman 異步地運行工做任務。php

認識Gearman

Gearman 只是一個分佈式程序調用框架,其主要由三部分組成,並經過暴露給使用方的 API 來完成任務委派和執行。html

組成角色

Gearman 中存在三個重要的角色,分別爲 Client、Job Server、Worker。mysql

  • Client:任務的發起者(能夠是 C、PHP、Java、Perl、MySQL 等);
  • Job Server:任務調度者,負責將 Client 委派的任務轉發給相應的 Worker(gearmand 進程管理);
  • Worker:任務的實際執行者(能夠是 C、PHP、Java、Perl 等);

Client、Job Server、Worker 典型的部署方案,以下圖:git

那麼,Gearman 是如何利用這三者進行任務的調度呢?github

能夠看出,在實際使用時,咱們只需調用 Gearman 已經實現了 Client 和 Worker 的 API,委派和註冊執行的任務,而無需關心任務的分發和機器的負載均衡問題。sql

外部API

到目前爲止,Gearman 已經提供了 C、Shell、Prel、 Nodejs、PHP、Python、Java、C#、Go、MySQL 等版本的 Client、Worker API,詳細信息見 這裏。本文只以 PHP 版爲例,列舉 Gearman 經常使用的 API 。vim

  • Client 端經常使用 API 列表:
功能描述 方法(GearmanClient 類中)
註冊一個 Client addServer(),單個
addServers(),多個
發起 Job 任務 doNormal(),阻塞會等待
doBackground(),非阻塞
doLow(),低優先級任務
doHigh(),高優先級任務
添加 Tash(一組 Job) addTask()、addTaskBackground()
addTaskHigh()、addTaskHighBackground()
addTaskLow()、addTaskLowBackground()
發起 Tash 任務 runTasks()
獲取最新操做的結果 returnCode()
註冊事件回調 setCompleteCallback()、setFailCallback()
說明:Job 是單個任務,每一個任務只會在一個 Worker 上執行,而 Task 是一組 Job,其多個子任務會分配到多個 Worker 上並行執行。
  • Worker 端經常使用 API 列表:
功能描述 方法(GearmanWorker 類中)
註冊一個 Worker addServer(),單個
addServers(),多個
註冊處理任務回調 addFunction()
等待和執行任務 work()
獲取最新操做的結果 returnCode()
  • Job 端也提供了 API,其經常使用列表爲:
功能描述 方法(GearmanJob 類中)
獲取任務攜帶的序列化數據 workload()
workloadSize(),獲取數據大小
向運行的任務發送數據 sendData()
說明:Gearman 各端之間數據交互時,數據須要進行序列化處理。

安裝Gearman

本文安裝 Gearman 須要兩步,第一步安裝守護程序(gearmand)的 Job,第二步安裝 PHP 擴展。api

安裝gearmand

首先,下載 Gearman 守護程序 gearmand 的 最新源碼,並解壓縮源碼包:php7

cd /usr/src
$ wget https://github.com/gearman/gearmand/releases/download/1.1.17/gearmand-1.1.17.tar.gz
$ tar zxvf gearmand-1.1.17.tar.gz

接着,安裝 gearmand 的依賴包,並編譯源碼安裝 gearmand:併發

$ yum install boost-devel gperf libuuid-devel libevent-devel
$ cd ./gearmand-1.1.17.tar.gz
$ ./configure
$ make && make install
# 安裝成功信息
Libraries have been installed in:
   /usr/local/lib
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

修改/etc/ld.so.conf配置文件,添加 MySQL 動態連接庫地址:

# /usr/local/mysql/lib爲MySQL動態連接庫libmysqlclient.so的目錄
$ echo "/usr/local/mysql/lib" >>/etc/ld.so.conf
# 使其生效
$ /sbin/ldconfig

而後,若是出現以下信息則表示安裝 gearmand 成功。

# 啓動Client和Worker
$ gearman
# 以下信息則表示成功
gearman    Error in usage(No Functions were provided).
Client mode: gearman [options] [<data>]

# 查看gearmand版本
$ gearmand -V
gearmand 1.1.17

安裝PHP擴展

從 PECL 下載最新 gearman 擴展(php7 需下載 最新源碼包),並解壓縮安裝:

$ cd /usr/src
$ wget http://pecl.php.net/get/gearman-1.1.2.tgz
$ tar zxvf gearman-1.1.2.tgz
$ cd gearman-1.1.2
$ /usr/local/php/bin/phpize
$ ./configure --with-php-config=/usr/local/php/bin/php-config
$ make && make install
# 安裝成功後信息
Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/

而後,配置 php.ini 文件:

$ php --ini
Loaded Configuration File:         /usr/local/php/lib/php.ini
$ vim /usr/local/php/lib/php.ini
#增長內容
extension=gearman.so

重啓 php-fpm 後,出現以下信息則表示安裝擴展成功。

$ php --info | grep "gearman"
gearman support => enabled
libgearman version => 1.1.17

運行Gearman

運行 Gearman ,實際上咱們須要使用到 Client、 Job、Worker 這三個角色。gearman 端實現了 Client 和 Worker 角色的功能 ,使用 PHP 時以擴展形式存在,gearmand 端則實現了 Job 角色的功能。

啓動Job

# 先建立日誌目錄
$ gearmand -d --log-file=/var/log/gearmand.log
若是啓動時出現 Address family not supported by protocol 錯誤,須要增長 -L 0.0.0.0參數。

查看啓動信息:

$ ps -ef | grep gearman
root     6048     1  0 19:56 ?        00:00:00 gearmand -d
# 監聽端口
$ netstat -tunpl | grep "gearmand"
tcp  0  0 0.0.0.0:4730  0.0.0.0:*   LISTEN  6048/gearmand

gearmand 命令的一些參數說明:

  • -b –backlog:監聽鏈接數量
  • -d –daemon:後臺運行
  • -f –file-descriptors:文件描述符的數量
  • -j –job-retries:移除不可用 Job 以前運行的次數
  • -l –log-file:日誌文件存放位置(默認記錄最簡單日誌)
  • -L –listen:監聽的 IP
  • -p –port:指定監聽端口
  • -q –queue-type:指定持久化隊列
  • -t –threads:使用的 I/O 線程數量
  • -u –user:啓動後,切換到指定用戶
  • --mysql-host:--mysql 系列爲 MySQL 持久化鏈接信息
爲了方便管理 gearmand,能夠將 gearmand 註冊爲一個 service 服務

啓動Client和Worker

經過 gearman 命令啓動 Client 和 Worker 並非必須的,這裏僅僅是爲了在命令行下測試工具。

首先,啓動一個 Worker,用於列出某個目錄的內容:

$ gearman -w -f ls -- ls -lh

而後,建立一個 Client,用於查找請求的一個做業:

$ gearman -f ls < /dev/null
total 4.0K
drwxr-xr-x. 21 www www 4.0K Jun 21 23:52 www

PHP使用Gearman

當啓動 Job 服務後,PHP 就能夠經過 Gearman 擴展,建立任務和綁定任務處理回調了。PHP 調用 Gearman 的 API 見 外部 API 部分,更多官方示例見 這裏

同步

Client 工做在同步阻塞模式,Client 發起任務後會等待至 Worker 執行任務結束。

  • Client 端
//Client.php
$client= new GearmanClient();
$client->addServer();

$msg = 'Hello World!';
echo "Sending $msg\n";
echo "Success: ", $client->doNormal("reverse", $msg), "\n";
  • Worker 端
//Worker.php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction("reverse", "reverse_fn");
echo "Waiting for job...\n";
while ($worker->work());

function reverse_fn($job) {
    $workload = $job->workload();
    echo "Workload: $workload\n";
    $result = strrev($workload);
    echo "Result: $result\n";
    return $result;
}

輸出結果爲:

//Client
Sending Hello World!
Success: !dlroW olleH

//Worker
Waiting for job...
Workload: Hello World!
Result: !dlroW olleH

三端的交互流程圖,以下:

異步

異步方式時,Client 端不會產生 IO 阻塞,能實現異步執行,在實際應用中能夠結合 fastcgi_finish_request() 函數或者 MQ 來異步使用。

  • Client 端
$client= new GearmanClient();
$client->addServer();
$client->setDataCallback("reverse_data");

$msg = 'Hello World!';
echo "Sending $msg\n";
$task = $client->addTaskBackground("reverse", $msg);
$msg = 'I am Gearman!';
echo "Sending $msg\n";
$task = $client->addTaskBackground("reverse", $msg);
$client->runTasks();

function reverse_data($task) {
    echo "Data: " . $task->data() . "\n";
}
  • Worker 端
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction("reverse", "reverse_fn");
echo "Waiting for job...\n";
while ($worker->work());

function reverse_fn($job)
{
    $workload = $job->workload();
    echo "Workload: $workload\n";
    $result = strrev($workload);
    $job->sendData($result);
    echo "Result: $result\n";
    return $result;
}

輸出結果爲:

//Client
Sending Hello World!
Data: !dlroW olleH
//Worker1
Waiting for job...
Workload: Hello World!
Result: !dlroW olleH
//Worker2
Waiting for job...
Workload: I am Gearman!
Result: !namraeG ma I

Gearman的管理工具

Gearman 可使用 GearmanManager 做爲管理工具,命令行下可使用 gearadmin 命令來進行簡易的管理。

$ gearadmin --show-jobs
32 ::7866:86a6:d87f:0%32 - : reserve

$ gearadmin --show-jobs
H:fhb:79    0    1    0
H:fhb:86    0    1    0

$ gearadmin --status
reverse    1    0    0
ls        0    0    0

總結

雖然 Gearman 出現的比較早,可是其支持跨語言調用特性,以及負載均衡的方式委派任務,在分佈式系統下,能夠更加合理高效地利用系統資源。在一些大型的密集型、異步後臺系統也已有成功部署的案例(數據抓取,庫存數據更新、郵件和短信服務等),另 PHP 藉助 Gearman 也能實現多任務處理方案。

推薦: 用 Gearman 分發 PHP 應用程序的工做負載
相關文章
相關標籤/搜索