Net_Gearmanを使ってPHPでGearman Workerを作る

 現在ライブドアの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をバックグラウンドで動かす)

4Gbpsを超えるWebサービス構築術
伊勢 幸一 池邉 智洋 栗原 由樹 山下 拓也 谷口 公一 井原 郁央
ソフトバンククリエイティブ
売り上げランキング: 192

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です