現在ライブドアの4Gbps本を購入して読んでますが(いきなり)、第2章で紹介されていた Gearman を使ったキューイングシステムがたいへんに便利そうでした。なので、積極的にマネしていきたいと思ってます。
4Gbps本には perl を使ったサンプルが紹介されていましたけど、現在の業務では主に PHP を使っているので、Gearman の PHP 実装を使ったワーカーやクライアントが作れないか調べているところです。以下、今のところの調査報告。
インストール
Server
Gearman のサーバ (gearmand) は、Ubuntu では apt-get で拾うことができるので、今回はそれを使用しました。
#sudo apt-get install gearman-server
/etc/default/gearman-server の「ENABLED="false"」を "true" に変更
#sudo /etc/init.d/gearman-server start
Net_Gearman
PEARのモジュールとして公開されている Net_Gearman をインストールします。
#sudo pear install Net_Gearman-0.2.3
Net_Gearmanは、github でも公開されています。このページに書かれているお手本を見れば、使い方は判ると思います。
Workerの作成
Net_Gearman は、ワーカーと実際に処理を実装するジョブを別のソースに分けて書く必要があります。
Net_Gearman_Workerでワーカーを作り、addAbilityでジョブ名を登録、beginWorkでクライアントからのジョブの待ち受けを開始、みたいな流れ。
gearman_worker.php
< ?php
require_once 'Net/Gearman/Worker.php';
$servers = array('localhost:7003');
try {
$worker = new Net_Gearman_Worker($servers);
$worker->addAbility('hello');
$worker->beginWork();
} catch (Net_Gearman_Exception $e) {
echo $e->getMessage() . "\n";
exit;
}
?>
#php gearman_worker.php
なお、「php gearman_worker.php &」とやってバックグラウンドで動作させるとそこでプロセスが止まってしまい、フォアグラウンドに戻してあげないとクライアントからの呼びかけに応答してくれませんでした。CLI版PHPの仕様?
Jobの作成
ワーカーから呼び出されるジョブですが、
- Net/Gearman/Job ディレクトリの配下に、
- ジョブ名.php というファイル名で、
記述する必要がある様です。Net/Gearman/Job は、ワーカープログラムから見える場所(includeのパス)に存在していないといけません。
なので、とりあえず今回は gearman_worker.php を置いたディレクトリに Net/Gearman/Job というディレクトリを作り、その下に hello.php を置くようにしました。
また、ジョブは
- Net_Gearman_Job_Common クラスを継承した、
- Net_Gearman_Job_ジョブ名 という名前のクラス
である必要があります。そのクラスの run という関数(メソッド)に、実際の処理を書きます。
Net/Gearman/Job/hello.php
< ?php
require_once 'Net/Gearman/Job/Common.php';
class Net_Gearman_Job_hello extends Net_Gearman_Job_Common
{
public function run($arg)
{
echo "Hello, " . $arg['name'] . "!\n";
}
}
?>
Clientの作成
クライアントはNet_Gearman_Clientを作ってジョブ名をメソッドとして記述することで、指定したジョブをバックグラウンドで実行します。ジョブには配列の形でデータを渡せます(内部的には JSON に変換しているらしい)。
gearman_client.php
< ?php
require_once 'Net/Gearman/Client.php';
$client = new Net_Gearman_Client('localhost:7003');
$client->hello(array('name' => 'World'));
?>
gearman_client.php を実行し、gearman_worker.php を実行しているコンソールに「Hello, World!」と表示されれば、我々の勝ちです。
とりあえずこんな形で PHP でワーカー+ジョブとクライアントを記述できますが、ワーカーをバックグラウンドで動かすと止まっちゃうので、そのままではジョブを PHP で書くのはあまり現実的ではないかなと思いました。
クライアントは上記の通りえらい簡単に書けるので、ワーカー+ジョブはperlで、クライアントはPHPでという形で運用するのが無難かと思います。perl+PHPの運用は、こちらの記事がとても参考になります。
(次回予告:System_Daemonを使ってNet_GearmanのWorkerをバックグラウンドで動かす)
伊勢 幸一 池邉 智洋 栗原 由樹 山下 拓也 谷口 公一 井原 郁央
ソフトバンククリエイティブ
売り上げランキング: 192