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::เอนทิตี ในขณะที่แฮ็กแก้ไข คุณสามารถลบสำเนียงและสิ่งที่คล้ายกันได้โดยใช้ 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 ควรเป็นค่าที่ไม่ซ้ำกัน ขึ้นอยู่กับค่าที่กำหนดโดยเบราว์เซอร์
วัตถุแคชจะเป็นวัตถุที่เข้าใจข้อความ get_object(), set(), ลบ() และ create_at() เช่นวัตถุ CHI มันถูกใช้เป็นแคชฝั่งเซิร์ฟเวอร์เพื่อลดความจำเป็นในการรันการเข้าถึงฐานข้อมูลอีกครั้ง
รายการอยู่ในแคชฝั่งเซิร์ฟเวอร์ตามค่าเริ่มต้นเป็นเวลา 10 นาที ซึ่งสามารถแทนที่ได้โดยส่วนหัว cache_control HTTP ในคำขอ และค่าเริ่มต้นสามารถเปลี่ยนแปลงได้ด้วยอาร์กิวเมนต์ cache_age เป็น init()
Save_to เป็นฟีเจอร์ที่จัดเก็บเอาต์พุตของเพจไดนามิกไปยังแผนผัง htdocs ของคุณและแทนที่ลิงก์ในอนาคตที่ชี้ไปยังหน้านั้นด้วยลิงก์แบบคงที่เพื่อหลีกเลี่ยงไม่ให้ผ่าน CGI เลย Ttl ถูกตั้งค่าเป็นจำนวนวินาทีที่เพจแบบคงที่ถือว่าใช้งานได้ ค่าเริ่มต้นคือ 10 นาที หากตั้งค่าเป็น 0 เพจจะคงอยู่ตลอดไป หากต้องการเปิดใช้งาน save_to จะต้องระบุข้อมูลและอาร์กิวเมนต์ภาษาด้วย จะทำงานได้ดีที่สุดเมื่อได้รับแคชด้วย ใช้เฉพาะในกรณีที่เอาต์พุตรับประกันว่าจะเหมือนกันกับชุดอาร์กิวเมนต์ที่กำหนด (เกณฑ์เดียวกันสำหรับการเปิดใช้งาน Generate_304) คุณสามารถปิดได้เป็นรายกรณีดังนี้:
my $params = CGI::Info->new()->params();
if($params->{'send_private_email'}) {
$buffer->init('save_to' => undef);
}
ข้อมูลเป็นอาร์กิวเมนต์ทางเลือกเพื่อให้ข้อมูลเกี่ยวกับสภาพแวดล้อม 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, ข้อมูล => CGI::Info->new() });
โดยทั่วไปแล้ว การส่งผ่านโดยการอ้างอิงจะดีกว่า เนื่องจากจะมีการคัดลอกไปยังสแต็กน้อยลง
หากคุณให้แคชแก่ init() จากนั้นให้แคช => undef ในภายหลัง แคชฝั่งเซิร์ฟเวอร์จะไม่ถูกใช้อีกต่อไป สิ่งนี้มีประโยชน์เมื่อคุณพบเงื่อนไขข้อผิดพลาดเมื่อสร้าง HTML และตัดสินใจว่าคุณไม่ต้องการเก็บเอาต์พุตไว้ในแคชอีกต่อไป
คำพ้องสำหรับ init เก็บไว้ด้วยเหตุผลทางประวัติศาสตร์
คืนค่าเป็นจริงหากเซิร์ฟเวอร์ได้รับอนุญาตให้จัดเก็บผลลัพธ์ไว้ในเครื่อง นี่คือค่าของ X-Cache ในส่วนหัวที่ส่งคืน
คืนค่าเป็นจริงหากเอาต์พุตถูกแคชไว้ หากเป็นเช่นนั้น หมายความว่ารูทีนราคาแพงทั้งหมดในสคริปต์ 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"
เมื่อใช้ Template ตรวจสอบให้แน่ใจว่าคุณไม่ได้ใช้เทมเพลตเพื่อส่งออกไปยัง STDOUT แต่คุณจะต้องบันทึกลงในตัวแปรและพิมพ์สิ่งนั้นแทน ตัวอย่างเช่น:
my $output;
$template->process($input, $vars, $output) || ($output = $template->error());
print $output;
สามารถสร้าง JavaScript แบบบั๊กกี้ได้หากคุณใช้เทคนิค