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 в заголовок. Если вы получаете ошибки о широких символах при печати, это означает, что вы забыли создать чистый HTML для символов, отличных от ASCII. См. HTML::Entities. В качестве обходного пути вы также можете удалить акценты и тому подобное, используя 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 должен быть уникальным значением, зависящим от значений, установленных браузером.
Объектом кэша будет объект, который понимает сообщения get_object(), set(), Remove() и Create_at(), например объект CHI. Он используется в качестве кэша на стороне сервера, чтобы уменьшить необходимость повторного доступа к базе данных.
По умолчанию элементы остаются в кэше на стороне сервера в течение 10 минут. Это можно переопределить с помощью HTTP-заголовка Cache_control в запросе, а значение по умолчанию можно изменить с помощью аргумента Cache_age на init().
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 — это необязательный аргумент, предоставляющий информацию о среде FCGI, например объект CGI::Info.
Logger будет объектом, который понимает функцию debug(), например объектом Log::Log4perl.
Чтобы сгенерировать заголовок Last_modified, вы должны указать объект кэша.
Init позволяет передавать ссылку на параметры. Итак, оба из них работают: используйте FCGI::Buffer; #... мой $buffer = FCGI::Buffer->new(); $b->init(generate_etag => 1); $b->init({generate_etag => 1, info => CGI::Info->new() });
Вообще говоря, передача по ссылке лучше, поскольку при этом в стек копируется меньше данных.
Если вы передадите кеш для init(), а затем позже дадите кэш => 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 должен быть безопасным даже в сценариях, которые выдают много разных результатов, например, в ситуациях электронной коммерции. Однако на таких страницах я настоятельно рекомендую установить дляgener_304 значение 0 и отправить HTTP-заголовок «Cache-Control: no-cache».
При использовании шаблона убедитесь, что вы не используете его для вывода в STDOUT, вместо этого вам нужно будет записать его в переменную и распечатать ее. Например:
my $output;
$template->process($input, $vars, $output) || ($output = $template->error());
print $output;
Может создавать ошибки в JavaScript, если вы используете технику