Настройка mod_gzip — сжатие трафика в Apache
15 декабря 2009
Непростое это дело — пытаться удерживать частоту появления новых постов в блоге на уровне хотя бы раз в неделю. Вечно всякие глупости в реале, вроде сессии, портят все планы :) Стиснув зубы, пишу очередной пост, стараясь, чтобы получилось интересно и полезно для читателей.
На всякий случай напоминаю, что mod_gzip — это модуль для веб-сервера Apache, предназначенный для сжатия трафика. Работает это очень просто — если модуль установлен, а браузер посетителя при запросе страницы говорит, что понимает сжатие gzip:
… то веб-сервер может послать ему не оригинал страницы, а ее сжатую gzip’ом версию:
Content-Encoding: gzip
Файлы вроде .css или JavaScript, которые по идее никогда не меняются, достаточно сжать один раз — вручную, или заставить модуль кэшировать архивированные копии. Для тестирования модуля я рекомендую воспользоваться сервисом http://web-sniffer.net/
На самом деле, в сети довольно много примеров настройки сжатия трафика с помощью mod_gzip, но я столкнулся с некоторыми трудностями при его использовании, о которых хотел бы рассказать. Ниже идет мой конфигурационный файл (mod_gzip.conf), используемый для сжатия веб-трафика этого блога. Его можно подключить к httpd.conf (или что там у вашего хостера? у моего — virtual.conf.manual) с помощью директивы Include:
Скачать текущую версию файла mod_gzip.conf можно здесь. А вот его код:
Пока все просто. Если модуль установлен, то включаем его.
mod_gzip_static_suffix .gz
AddEncoding gzip .gz
Опция mod_gzip_can_negotiate говорит модулю, что в случае, если пользователь запросил файл, скажем main.css, а в одной директории с ним лежит main.css.gz (расширение задается с помощью mod_gzip_static_suffix), то нужно отдать main.css.gz. Разумеется, это только в том случае, если клиент поддерживает gzip-сжатие. Таким образом мы можем заранее сжать все файлы, которые в последствии не собираемся редактировать, сэкономив тем самым немного процессорного времени.
Если создавать руками сжатые копии файлов для предыдущих опций влом, можно поставить здесь Yes, загрузить нужные файлы (для них модулем будут созданы сжатые копии), а затем поставить обратно No. Сжатые копии перезаписываются при каждом новом обращении к файлам, пока здесь не будет прописан No.
mod_gzip_keep_workfiles No
Тут можно сменить каталог для временных файлов и указать, требуется ли их хранить. Последнее может пригодиться для отладки.
mod_gzip_maximum_file_size 500000
mod_gzip_maximum_inmem_size 60000
Минимальный/максимальный размер файла, необходимый для того, чтобы он сжимался, и максимальный размер файла, при котором сжатие будет происходить полностью в памяти соответственно.
mod_gzip_handle_methods GET POST
mod_gzip_item_exclude reqheader "User-agent: Mozilla/4.0[678]"
mod_gzip_item_include handler ^cgi-script$
Минимальная версия протокола — HTTP/1.0, производить сжатие только при GET и POST запросах, исключить клиентов, которые заявляют, что поддерживают gzip, хотя на самом деле это не так и включить сжатие данных, выдаваемых CGI-скриптами.
mod_gzip_item_include mime ^application/x-httpd-php
mod_gzip_item_include mime ^application/xml
mod_gzip_item_exclude mime ^image/
mod_gzip_item_include file \.js$
mod_gzip_item_include file \.css$
Сжимаем текст, XML (в том числе SiteMap и RSS), JavaScript, CSS файлы и данные, выдаваемые скриптами на PHP. Картинки не сжимаем.
Тут нужно обратить внимание на несколько моментов. Во-первых, браузер Netscape 4 неправильно обрабатывает сжатые css-файлы, и это есть плохо. К счастью, 99% посетителей сидят под Firefox, Chrome, Opera или IE, так что беспокоиться об одном единственном криво написанном браузере, которым практически никто не пользуется, беспокоиться не стоит. Во-вторых, во многих мануалах предлагается вместо 16-ой строки написать такое:
То есть, с долларом на конце, обозначающим (если вы подзабыли регулярные выражения) конец строки. Так вот, оказывается, что это не всегда работает, в зависимости, судя по всему, от версии mod_gzip. Видимо, это связано с тем, что веб-сервер передает значение Content-Type в таком виде:
Как видите, после text/html никакого конца строки на самом деле нет.
Позволяет mod_gzip декодировать ответы сервера с
Если вы не знаете, что это такое, то просто поверьте, что это действительно должно быть в конфиге. Todo: написать описание протокола HTTP и объяснить, что такое chunked.
CustomLog /full/path/to/logs/mod_gzip.log common_with_mod_gzip_info2
Формат записей в лог-файле и путь к лог-файлу. Логи следует включить только на время тестирования mod_gzip, потом они будут только зря занимать место на диске. Вот как примерно будут выглядеть записи в mod_gzip.log:
123.45.67.89 - - [14/Dec/2009:23:38:56 +0300] "eax.me GET /perl-hacks/ HTTP/1.1" 200 7282 Content-Type: 'text/html' mod_gzip: DECHUNK:OK In:25355 - Out:6943 = 73 pct.
В первой строке написано, что файл select-dict.png был передан в несжатом виде, поскольку мы сказали не сжимать картинки (они и так неплохо сжаты, если это не bmp). Во второй — что при запросе статьи Интересные примеры на Perl был успешно выполнен dechunk и произведено сжатие html-кода аж на 73%.
В целом, мое мнение относительно mod_gzip следующее — пользоваться им можно и нужно. Главным образом, потому что это позволяет вашим посетителям (и поисковикам) быстрее загружать страницы и экономить трафик. Большинство хостеров сегодня уже не вводят ограничений на объем трафика ваших сайтов и использование CPU их не сильно беспокоит (в отличие от числа запущенных процессов и объема потребляемой оперативной памяти), потому экономия со стороны вебмастера играет второстепенную роль.
Дополнение: Еще один способ уменьшить объем трафика — прогнать HTML и JavaScript код через обфускатор.
Метки: Сайтостроение, Сети.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.