FCGI::Buffer - FCGI 出力の検証、キャッシュ、最適化
バージョン0.19
FCGI::Buffer は、生成した HTML をHTML::Lint
に渡すことによって検証します。
FCGI::Buffer は、出力を削減、フィルタリング、圧縮して送信を高速化し、クライアントとサーバーのキャッシュをほぼシームレスに利用することにより、FCGI プログラムを最適化します。
クライアント キャッシュを利用するには、つまり、同じデータを要求するサーバーへの不必要な呼び出しを減らすには、次のようにします。
use FCGI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
);
# ...
}
サーバー キャッシュも利用するには、つまり、別のクライアントが同じデータを要求したときに再生成される出力を保存するには、キャッシュを作成する必要があります。しかし、それは簡単です。
use FCGI;
use CHI;
use FCGI::Buffer;
# ...
my $request = FCGI::Request();
while($request->FCGI::Accept() >= 0) {
my $buffer = FCGI::Buffer->new();
$buffer->init(
optimise_content => 1,
lint_content => 0,
cache => CHI->new(driver => 'File')
);
if($buffer->is_cached()) {
# Nothing has changed - use the version in the cache
$request->Finish();
next;
# ...
}
}
コード変更を公開する前のデバッグ中など、サーバー側キャッシュの使用を一時的に禁止するには、NO_CACHE 環境変数をゼロ以外の値に設定します。これにより、ETag がヘッダーに追加されることも停止されます。印刷でワイド文字に関するエラーが発生した場合は、非 ASCII 文字で純粋な HTML を出力するのを忘れたことを意味します。 「HTML::エンティティ」を参照してください。ハックの回避策として、Text::Unidecode を使用してアクセントなどを削除することもできます。これはうまく機能しますが、実際に望むものではありません。
FCGI::Buffer オブジェクトを作成します。各 FCGI::Accept に対してこれらのいずれかを実行します。
さまざまなオプションを設定し、デフォルト値をオーバーライドします。
# Put this toward the top of your program before you do anything
# By default, generate_tag, generate_304 and compress_content are ON,
# optimise_content and lint_content are OFF. Set optimise_content to 2 to
# do aggressive JavaScript optimisations which may fail.
use FCGI::Buffer;
my $buffer = FCGI::Buffer->new()->init({
generate_etag => 1, # make good use of client's cache
generate_last_modified => 1, # more use of client's cache
compress_content => 1, # if gzip the output
optimise_content => 0, # optimise your program's HTML, CSS and JavaScript
cache => CHI->new(driver => 'File'), # cache requests
cache_key => 'string', # key for the cache
cache_age => '10 minutes', # how long to store responses in the cache
logger => $self->{logger},
lint_content => 0, # Pass through HTML::Lint
generate_304 => 1, # When appropriate, generate 304: Not modified
save_to => { directory => '/var/www/htdocs/save_to', ttl => 600, create_table => 1 },
info => CGI::Info->new(),
lingua => CGI::Lingua->new(),
});
cache_key が指定されていない場合は、一意ではない可能性のあるキャッシュ キーが生成されます。 cache_key は、ブラウザによって設定された値に応じた一意の値である必要があります。
キャッシュ オブジェクトは、CHI オブジェクトなど、get_object()、set()、remove()、created_at() メッセージを理解するオブジェクトになります。これは、データベース アクセスを再実行する必要性を減らすためにサーバー側のキャッシュとして使用されます。
アイテムはデフォルトで 10 分間サーバー側キャッシュに残ります。これはリクエスト内のcache_control HTTPヘッダーによってオーバーライドでき、デフォルトはinit()のcache_age引数によって変更できます。
Save_to は、動的ページの出力を htdocs ツリーに保存し、そのページを指す今後のリンクを静的リンクに置き換えて、CGI をまったく経由しないようにする機能です。 Ttl は、静的ページがライブであるとみなされる秒数に設定されます。デフォルトは 10 分です。 0 に設定すると、ページは永久に存続します。 save_to を有効にするには、info 引数と lingua 引数も指定する必要があります。キャッシュも指定すると最も効果的です。指定された引数セット (generate_304 を有効にするための同じ基準) と出力が同じであることが保証されている場合にのみ使用してください。次のように、ケースバイケースでオフにすることができます。
my $params = CGI::Info->new()->params();
if($params->{'send_private_email'}) {
$buffer->init('save_to' => undef);
}
Info は、CGI::Info オブジェクトなど、FCGI 環境に関する情報を与えるオプションの引数です。
Logger は、Log::Log4perl オブジェクトなど、debug() を理解するオブジェクトになります。
last_modified ヘッダーを生成するには、キャッシュ オブジェクトを指定する必要があります。
Init を使用すると、オプションの参照を渡すことができます。したがって、これらは両方とも機能します。 FCGI::Buffer を使用します。 #... 私の $buffer = FCGI::Buffer->new(); $b->init(generate_etag => 1); $b->init({generate_etag => 1, info => CGI::Info->new() });
一般的に言えば、スタックへのコピーが少なくなるため、参照渡しの方が優れています。
init() にキャッシュを与えてから、cache => undef を与えると、サーバー側のキャッシュは使用されなくなります。これは、HTML の作成時にエラー状態を見つけ、出力をキャッシュに保存したくないと判断した場合に便利です。
init の同義語。歴史的な理由から保持されています。
サーバーが結果をローカルに保存できる場合は true を返します。これは、返されたヘッダーの X-Cache の値です。
出力がキャッシュされている場合は true を返します。そうであれば、結果がすでにキャッシュに保存されているため、FCGI スクリプト内の高価なルーチンはすべてバイパスできることを意味します。
# Put this toward the top of your program before you do anything
# Example key generation - use whatever you want as something
# unique for this call, so that subsequent calls with the same
# values match something in the cache
use CGI::Info;
use CGI::Lingua;
use FCGI::Buffer;
my $i = CGI::Info->new();
my $l = CGI::Lingua->new(supported => ['en']);
# To use server side caching you must give the cache argument, however
# the cache_key argument is optional - if you don't give one then one will
# be generated for you
my $buffer = FCGI::Buffer->new();
if($buffer->can_cache()) {
$buffer->init(
cache => CHI->new(driver => 'File'),
cache_key => $i->domain_name() . '/' . $i->script_name() . '/' . $i->as_string() . '/' . $l->language()
);
if($buffer->is_cached()) {
# Output will be retrieved from the cache and sent automatically
exit;
}
}
# Not in the cache, so now do our expensive computing to generate the
# results
print "Content-type: text/htmln";
# ...
ナイジェル・ホーン、
FCGI::Buffer は、電子商取引の状況など、さまざまな出力を多数生成するスクリプト内でも安全である必要があります。ただし、そのようなページでは、generate_304 を 0 に設定し、HTTP ヘッダー「Cache-Control: no-cache」を送信することを強くお勧めします。
テンプレートを使用する場合は、STDOUT への出力には使用しないようにしてください。代わりに、変数にキャプチャして出力する必要があります。例えば:
my $output;
$template->process($input, $vars, $output) || ($output = $template->error());
print $output;