2010-03-08 2 views
4

Скажем, у меня нет mod_deflate, скомпилированного в apache, и я не хочу перекомпилировать прямо сейчас. Каковы недостатки для ручного подхода, например. что-то вроде:Ручная альтернатива mod_deflate

AddEncoding x-gzip .gz 
RewriteCond %{HTTP_ACCEPT_ENCODING} gzip 
RewriteRule ^/css/styles.css$ /css/styles.css.gz 

(Примечание: Я знаю, что специфика этого RewriteCond должны быть переделаны слегка)

+1

Это означает, что каждый раз, когда вы меняете какой-либо файл, вы должны убедиться, что вы создали версию gzipped, или вы рискуете либо (1), когда gzipped пользователи будут обслуживать более старую версию файла или (2) случайным образом Если версия gzipped еще не выполнена. Только одна ошибка, и внезапно у вас есть Гейзенбуг, который очень сложно отследить. –

+0

Да - конкретный прецедент здесь используется только для очень небольшого количества редко изменяющихся файлов, поэтому, хотя это и остается недостатком такого подхода, вероятно, это не шоу-стоппер. Я подумал о добавлении в цепочку «RewriteCond% {REQUEST_FILENAME} -f», но тогда возникает обеспокоенность по поводу неэффективности постоянной статистики файла (я не уверен, как/если apache кэширует эту информацию) –

ответ

3

Другой альтернативой является пересылка всего на PHP-скрипт, который gzips и кэширует все «на лету». По каждому запросу он будет сравнивать временные метки с кешированной версией и возвращать это, если он новее исходного файла. С помощью PHP вы также можете перезаписать заголовки HTTP, поэтому он обрабатывается правильно, как если бы он был GZIPed самим Apache.

Нечто подобное может сделать работу за вас:

.htaccess

RewriteEngine On 
RewriteRule ^(css/styles.css)$ cache.php?file=$1 [L] 

cache.php:

<?php 
// Convert path to a local file path (may need to be tweaked) 
cache($_GET['file']); 

// Return cached or raw file (autodetect) 
function cache($file) 
{ 
    // Regenerate cache if the source file is newer 
    if (!is_file($file.'.gz') or filemtime($file.'.gz') < filemtime($file)) { 
    write_cache($file); 
    } 

    // If the client supports GZIP, send compressed data 
    if (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) and strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) { 
    header('Content-Encoding: gzip'); 
    readfile($file.'.gz'); 
    } else { // Fallback to static file 
    readfile($file); 
    } 
    exit; 
} 

// Saved GZIPed version of the file 
function write_cache($file) 
{ 
    copy($file, 'compress.zlib://'.$file.'.gz'); 
} 

вам нужны права на запись для Apache для создания кэшированных версий , Вы можете немного изменить скрипт, чтобы хранить кешированные файлы в другом месте.

Это не было тщательно протестировано, и его, возможно, нужно немного изменить для ваших нужд, но идея все там и должна быть достаточной, чтобы вы начали.

+1

Вероятно, вы хотите перевернуть этот знак больше, чем знак в знак меньше. Кроме этого, выглядит хорошо. – Alex

+0

Спасибо, вы, конечно, правы;) –

+0

Да, моя ссылка на скрипт на стороне сервера в более раннем комментарии я думал об этом. Однако большое использование 'compress.zlib: //'; Раньше я не сталкивался с этим. –

1

Там, кажется, не будет большой разницы в производительности между ручные и автоматические подходы. Я сделал несколько сканеров Apache с автоматическим и ручным сжатием, и оба раза были в пределах 4% друг от друга.

Очевидным недостатком является то, что перед развертыванием вам придется вручную сжать файлы CSS. Другая вещь, которую вы, возможно, захотите сделать очень уверенной, состоит в том, что вы правильно настроили конфигурацию. Я не мог заставить wget автоматически декодировать css, когда я попробовал ручной подход, а сообщения ab также перечисляли сжатый размер данных вместо несжатых, как при автоматическом сжатии.

+0

Ручное сжатие может это не проблема. В этом случае я имею дело с файлами, которые редко меняются, и есть/возможность /, что сжатие может быть автоматизировано с помощью сценария на стороне сервера. Информация от wget очень полезна, однако - спасибо за исследование. Думаю, мне придется проверить это сам, если я на самом деле собираюсь его использовать, но отличная информация о различиях в производительности - большое спасибо. –

1

Вы также можете использовать mod_ext_filter и трубить вещи через gzip. На самом деле, это один из примеров:

 
# mod_ext_filter directive to define the external filter 
ExtFilterDefine gzip mode=output cmd=/bin/gzip 

<Location /gzipped> 
# core directive to cause the gzip filter to be 
# run on output 
SetOutputFilter gzip 

# mod_header directive to add 
# "Content-Encoding: gzip" header field 
Header set Content-Encoding gzip 
</Location> 

Преимущество этого в том, что это на самом деле, очень легко ... Недостаток заключается в том, что будет дополнительным fork() и exec() на каждый запрос, который, очевидно, будет иметь небольшой влияние на производительность.

Смежные вопросы