読者です 読者をやめる 読者になる 読者になる

gearmandのHTTPプロトコル

Gearman

gearmanのHTTPプロトコルを試してみようと思ったところ、だいぶハマったのでメモを残しておく。

gearmand起動オプションの注意点

HTTPプロトコルのサポートはバージョン0.8から含まれており標準で有効になっているはず。確認するには、--helpで"http Options"が含まれているかチェック。

$ gearmand --help
gearmand 0.10 - https://launchpad.net/gearmand

usage: gearmand [OPTIONS]

... 略

libmemcached Options:

     --libmemcached-servers=SERVER_LIST List of Memcached servers to use.

libsqlite3 Options:

     --libsqlite3-db=DB       Database file to use.
     --libsqlite3-table=TABLE Table to use.

http Options:

     --http-port=PORT Port to listen on.

いつの間にか永続化プラグインとしてsqliteもサポートするようになっていた。

HTTPプロトコルを有効にしてgearmandを起動するには、

$ gearmand --protocol=http --http-port=8000 --port=4730

のように、--protocol=httpオプションでHTTPプロトコルを有効にする必要がある。これが分からなくてかなり長い時間ハマり、最終的にソースコードを読んで解決した・・・

上の例ではHTTPプロトコルでリッスンするポートを8000、通常のGearmanプロトコルでリッスンするポートを4730(標準のポート)に指定している。この二つに同じポート番号を指定することはできない。

gearmanコマンドでテスト

HTTPプロトコルを試してみるために、まずワーカープロセスを起動する。

PythonPerlでプログラムを書いてもいいが、ちょっと試してみる程度ならば、gearmanコマンドでOK。例えば、

$ gearman -p 4730 -w -f server_date date

ならば、ポート4730で(-p 4730)でワーカーモード(-w)で起動し、server_dateという名前(-f server_date)でdateコマンドを登録する、という意味。

このワーカーを呼び出すにも、gearmanコマンドをクライアントモードで使って、

$ gearman -p 4730 -s -f server_date

"-p", "-f"オプションの意味はワーカーモードと同じ。-sをつけると標準入力からの読み込みをスキップする。逆に何か引数を与えて登録した関数を呼び出したい場合には、

$ gearman -f some_func < /path/to/some/file

や、

$ gearman -f some_func "arguments come here"

のようにする。gearmanコマンドはいろいろ応用が利きそうで興味深い。

HTTPプロトコルを試す

上記の時刻を返すワーカーをHTTPプロトコルを使って試してみる。

$ curl -H 'X-Gearman-Background: false' http://localhost:8000/server_date
Fri Oct  2 23:40:23 JST 2009

URLは、

http://(Gearmanサーバーのホスト):(Gearmanサーバーのポート)/(関数名)

のようになる。

HTTPヘッダーに"X-Gearman-Background: false"を付けているのは、これがないとワーカーの結果を待たないバックグラウンドタスクとして解釈されてしまうため。

逆にバックグランドタスクとして登録するには、

$ curl -H 'X-Gearman-Background: true' http://localhost:8000/server_date

のように、X-Gearman-Backgroundをtrueに指定するか、このヘッダー自体を省略する。その場合は、登録されたタスクを一意に示すID(X-Gearman-Job-Handle)がレスポンスヘッダーとして返される。

$ curl --verbose http://localhost:8000/server_date
* About to connect() to localhost port 8000 (#0)
*   Trying ::1... Connection refused
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /server_date HTTP/1.1
> User-Agent: curl/7.19.6 (x86_64-redhat-linux-gnu) libcurl/7.19.6 NSS/3.12.4.1 Beta zlib/1.2.3 libidn/1.9 libssh2/1.0
> Host: localhost:8000
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< X-Gearman-Job-Handle: H:gearman.examle.com:11
< Content-Length: 29
< Server: Gearman/0.10
<
Fri Oct  2 23:47:15 JST 2009
* Closing connection #0

リクエストを送信する際に有効なヘッダーは以下の通り。それぞれの意味合いは、HTTP/Gearmanプロトコルのそれと同じなので自明だと思う。

  • Content-Length: SIZE
  • Connection: Keep-Alive
  • X-Gearman-Unique: UNIQUE_KEY
  • X-Gearman-Background: true
  • X-Gearman-Priority: HIGH | LOW