Perlbal::Manual::Plugins - プラグインの作成と使用
Perlbal 1.78.
Perlbalのプラグインの作成と使用の仕方。
Perlbal はこのドキュメントの下のほうで説明する関数のセットを実装するPerlbal::Plugin::*
のモジュールを使ってプラグインをサポートします。
これらのプラグインはPerlbal本体と一緒に出荷されていますが、その他のものはCPANで見つけることができます (独自のプラグインを作成し、ローカルでのみ利用可能にすることもできます)。
プラグインを使うためには、まずそれをロードしなければなりません; Perlbalの設定ファイルに以下のように追加します:
Load MyPlugin
これは プラグイン Perlbal::Plugin::MyPlugin
をロードします。
各プラグインは設定するために独自の方法を持っているでしょう(設定を全く必要しないものもあります)。ですので、それらのドキュメント(あるいはコード)を参照する必要があるでしょう。
一般的に(常にではありません)、プラグインによってサービスに追加のパラメータを設定することができます。たとえば:
LOAD MaxContentLength CREATE SERVICE example SET max_content_length = 100000 SET plugins = MaxContentLength
max_content_length
は the Perlbal::Plugin::MaxContentLength manpage のパラメータです。
If you're worried that two plugins may have the same parameter, of if you simply want to define those variables all in the same spot and thus will be doing it outside of the plugin's context, you can use the more verbose syntax:
SET my_service.my_plugin.my_variable = my_value
いくつかのプラグインはサービスごとに宣言されなければならないことに注意してください。従ってこの行は:
SET plugins = MaxContentLength
The plugins
parameter (a list of strings separated by commas or spaces) defines which plugins are acceptable for a service.
プラグインをロードしようとして以下のエラーメッセージを受け取るかも知れません:
ERROR: Can't locate Perlbal/Plugin/MyPlugin.pm in @INC
これは、プラグインがインストールされていないか、perlbalが見つけられないことを意味します。(おそらく、perlbalを実行するために使われているperlではなく、異なるバージョンのperlの中でインストールされています)
Perlbalは多くの関数を実装する Perlbal::Plugin
何前空間の下のパッケージからできています: register
, unregister
, load
および unload
.
これらのステップと関数(および、あなたが定義あるいは使用できるいくつかのヘルパー関数)は以下で説明されます。
注意してください: Perlbalは単一プロセス、非同期のwebサーバです。 プラグイン内でブロックするようなことや、他のリクエストが同時に提供されないことは、してはいけません。
While there are many ways of creating a package, we'd recommend that you use something to do it for you. A good option is the Module::Starter manpage.
(note: if you really want to, you can just create a file with your package and use it; by using something like the Module::Starter manpage you're making sure that several pitfalls are avoided, lots of basic rules are followed and that your package can easily be made available as a distribution that you can deploy on any machine - or, if you feel so inclined, upload to CPAN - in a simple way)
Let's assume you want to create a plugin that checks requests for a X-Magic
header and, if present, add an header X-Color
to the response when serving a file. Let's assume your plugin will be called Perlbal::Plugin::ColorOfMagic
.
the Module::Starter manpage をインストールしていると、パッケージを作成するコマンドを実行するコマンドがあります。
$ module-starter --module=Perlbal::Plugin::ColorOfMagic --author="My name" --email=my@email.address
That should create a file tree that you can get better acquainted with by reading the Module::Starter manpage's fine documentation. この例では、読む必要があるファイルは lib/Perlbal/Plugin/ColorOfMagic.pm
にあります。
このファイルはおそらく以下のようなものから始まります:
package Perlbal::Plugin::ColorOfMagic;
use warnings; use strict;
このファイルに新しい関数を追加する必要があるでしょう。これらは以下で説明されます。
(note: upon creating this package, some boilerplate documentation will also be present on the file; you should revise it and even remove bits that don't feel right for your plugin)
register
はサービスにプラグインが追加される時に呼ばれます。This is where you register your plugin's hooks, if required (see the Perlbal::Manual::Hooks manpage for the list of existing hooks and further documentation on how they work).
For the sake of our example (Perlbal::Plugin::ColorOfMagic
, see above), what we want to do is register a hook that modifies the response headers; that means we want a modify_response_headers
hook.
しなければならないのはこれです:
sub register { my ($class, $service) = @_;
my $my_hook_code = sub {
my Perlbal::ClientHTTPBase $cp = shift;
if ( $cp->{req_headers}->header('X-Magic') ) { $cp->{res_headers}->header( 'X-Color', 'Octarine' ); }
return 0; };
$service->register_hook('ColorOfMagic','modify_response_headers', $my_hook_code); }
register
の中で、ColorOfMagic
modify_response_headers
ホックを登録するためにregister_hook
を読んでいます。Its code, that will run "when we've set all the headers, and are about to serve a file" (see the Perlbal::Manual::Hooks manpage), receives a the Perlbal::ClientHTTPBase manpage object (you can see what kind of object your hook will receive on the Perlbal::Manual::Hooks manpage). X-Magic
がリクエストに設定されているかを調べ、もしそうであれば、Octarine
への応答にX-Color
をヘッダを設定します。
ホックがreturn 0
で終わることに注意してください。trueを返すことはバックエンドへの接続を停止しクライアントへの応答を自身で送りたいことを意味するからです。
unregister
はプラグインがサービスから削除された時に呼ばれます。ここでホックを登録からはずすことは標準的な良い慣習です。以下のようになります:
sub unregister { my ($class, $service) = @_; $service->unregister_hooks('ColorOfMagic'); return 1; }
一つの単独のホックを登録から外すためにunregister_hook
を使うこともできます:
$service->unregister_hook('ColorOfMagic', 'modify_response_headers');
load
はプラグインがロード(あるいは再ロード)された時に呼ばれます。
ここはプラグインの初期化を実行すべき場所で、変数のセットアップから管理コマンドの登録まで及びます(コマンドを登録するには、このドキュメントの下のほうの manage_command
を見てください)。
my $color;
sub load { my $class = shift;
$color = 'Octarine';
return 1; }
load
は常に定義されなければなりませんが、本当に必要ない場合には単純にtrueを返すようにすることができます。
sub load { return 1; }
unload
はプラグインがアンロードされる時に呼ばれます。ここではクリーンアップのタスクを実行する必要があります。
unload
が常に定義されなければなりませんが、本当に必要ない場合には単純にtrueを返すようにすることができます。
sub unload { return 1; }
何かを登録した場合には、unregister_global_hook
を呼ぶことを忘れないでください(このドキュメントの下のほうのmanage_command
を見てください。私たちが何について話しているのか分かるでしょう)。
load
はプラグインがロードされた時に呼ばれますが、register
はプラグインがサービスにセットされた時に呼ばれます。
このことは、グローバルホックを登録するなどグローバルなものについては load
を使う必要があり、サービスホックの登録などサービス固有のものについては register
を使わなければならないことを意味します。
dumpconfig
は必須ではありません。
Perlbalを管理する時に (the Perlbal::Manual::Management manpageを見てください)、設定のダンプを出力することになる dumpconfig
コマンドを送信することができます。
グローバル設定は別として、 dumpconfig
関数を実装する個々のプラグインもその関数が呼ばれるでしょう。
dumpconfig
は表示するメッセージの配列を返さなければなりません。
sub dumpconfig { my ($class, $service) = @_;
my @messages;
push @messages, "COLOROFMAGIC is $color";
return @messages; }
繰り返しますが、dumpconfig
は必須ではなく、あなたのプラグインにとって意味がある場合にのみ実装してください。
Adding a tunable will allow you to set its value within each plugin:
LOAD MyPlugin CREATE SERVICE my_service SET my_new_parameter = 42 SET plugins = MyPlugin ENABLE my_service
add_tunable
can be used by plugins that want to add tunables so that the config file can have more options for service settings.
sub load {
Perlbal::Service::add_tunable( my_new_parameter => { check_role => '*', check_type => 'int', des => "description of my new parameter", default => 0, }, ); return 1;
}
check_role
は値によってどのroleが設定されるかを定義します( (reverse_proxy
, web_server
, など)。*
の値は、その値が全てのroleのために設定されることを意味します。
check_type
に利用可能な値は、 enum
, regexp
, bool
, int
, size
, file
, file_or_none
および directory_or_none
です。確認のcheck_type
を設定しようとすると、Unknown check_type エラーメッセージが表示されるでしょう。
check_type
には種類を検証に使われるcode referenceを含むこともできます。
check_type => sub { my $self = shift; my $val = shift; my $emesg = shift;
... },
このcode referenceはtrueまたはfalseを返さなければなりません。falseを返すと、$emesg
の内容 (これは、関数にリファレンスとして渡されます)はエラーメッセージとして使われるでしょう。
check_type
の利用可能な値の良い例があります:
Boolean value. 定義される必要があり、Perlの値としてチェックされるでしょう。
値は定義される必要があり、その内容は既存のディレクトリである必要があります(perlの -d スイッチで検証されます)。
受け付け可能な値を含む配列のリファレンス:
check_type => [enum => ["yellow", "blue", "green"]],
ファイル名。perlの-f スイッチで検証されます。
ファイル名。perlの-f スイッチあるいはデフォルト値で検証されます。
整数値。/^\d+$/
で検証されます。
正規表現。
The correct form of setting a regexp tunable is by setting it as an array reference containing the type (regexp
), the regular expression and a message that can explain it:
check_type => ["regexp", qr/^\d+\.\d+\.\d+\.\d+:\d+$/, "Expecting IP:port of form a.b.c.d:port."],
サイズ。/^(\d+)[bkm]$/
で検証されます。
perlbalは不明な設定コマンドを捕らえ、それらをmanage_command.*
の形式のホックに一致するかを試します。
サーバの時間を見ることができる管理コマンドtime
を設定したいとしましょう。
sub load {
Perlbal::register_global_hook('manage_command.time', sub { my $time = localtime time;
return [ "It is now:", $time ]; });
return 1;
}
テキストメッセージを表示したい場合は、配列のリファレンスを返す必要があります; 各値は改行文字を付けて表示されるでしょう。
time It is now: Wed Dec 1 19:08:58 2010
ホックで追加のパラメータをパースする必要がある場合は、関数が受け取るthe Perlbal::ManageCommand manpageオブジェクト上で parse
および args
を使用することができます。
my $mc = shift;
$mc->parse(qr/^time\s+(today|tomorrow)$/, "usage: TIME [today|tomorrow]");
my ($cmd, $choice) = $mc->args;
これにより、 today
または tomorrow
のうちの一つでなければならない引数を付けてコマンドを呼び出すことができます。
register_setter
によりプラグインに以下のような構文を使ってパラメータを定義することができます;
SET my_service.my_plugin.my_variable = my_value
例えば:
SET discworld.colorofmagic.color = 'Orange'
load
の中でregister_setter
を使った新しいセッターを設定する方法がこれです:
my $color;
sub load { $color = 'Octarine';
$svc->register_setter('ColorOfMagic', 'color', sub { my ($out, $what, $val) = @_; return 0 unless $what && $val;
$color = $val;
$out->("OK") if $out;
return 1; });
return 1; }
selector
サービスを使って動作するプラグインについては、時にはselector
自身を上書きたいと思うでしょう。
register
の中でこれをすることができます:
sub register { my ($class, $svc) = @_;
$svc->selector(\&my_selector_function);
関数をunregisterすることを忘れないでください:
sub unregister { my ($class, $svc) = @_; $svc->selector(undef); return 1; }
selector
関数はthe Perlbal::ClientHTTPBase manpage オブジェクトを受け取ります。
my Perlbal::ClientHTTPBase $cb = shift;
selector
関数の中で、どのサービスがリクエストを前に進めるかを以下のようにして設定することができます:
my $service = Perlbal->service($service_name); $service->adopt_base_client($cb); return 1;
どうやってこれをするかの例は、the Perlbal::Plugin::Vhosts manpage または the Perlbal::Plugin::Vpaths manpage を見てください。
以下は良く知られているプラグインのリストです:
IPとネットマスクに基づいた基本的なアクセス制限。
Perlbal webサーバ応答にヘッダを追加します。
URL内の先頭のパス部分を自動的に削除します。
See which backend served the request.
Perlのサブルーチンを使ってPerlbalリクエストを処理します。
プラグイン構造を使ってPerlbalがどのようにadd-onサービスを作成するかを実演するサンプルのプラグイン。
サービスのSSLに応じてカスタムヘッダを追加します。
リバースプロキすを使ってFLVストリーミングを有効にします。
Perlbal内でX-Forwarded-Forヘッダを付け替えます。
いくつかのリクエストを高優先度にします。
複数の入れ子の設定ファイルを許可します。
Content Delivery Networks をサポートします。
大きなリクエストを拒否します。
クライアントが If-Modified-Since
ヘッダを送信する時に、自動的に304 Not Modified を応答します。
Perlbal上のPSGI web サーバ。
Perlbalがパレットを変更したイメージを提供することができるプラグイン。
Simple queue length header inclusion plugin.
Perlbalの領域でリダイレクトを行うプラグイン。
基本的なPerlbal統計を集めるもの。
Perlbalのためのセッションの親和性。
頻繁に接続するホストからの接続を絞る。
信頼できないヘッダを削除します。
正規表現を使ってURLをマッチさせます。
名前ベースのバーチャルホスト。
パスによってselectします (selectorのroleのみ)。
リバースプロキシされたリクエストに X-Forwarded-Port および/あるいは X-Forwarded-Protoヘッダを任意に追加することができるPerlbalのプラグイン。
the Perlbal::Manual::Hooks manpage, the Perlbal::Manual::Internals manpage.
conf/ の下にサンプルの設定ファイルがあります; これらのうちのいくつかは既存のプラグインを使用および設定する方法の例です: the Perlbal::Plugin::EchoService manpage のための echoservice.conf、the Perlbal::Plugin::VHosts manpageのための virtual-hosts.conf など。