Настройка mod_gzip – сжатие трафика в Apache

10

Непростое это дело – пытаться удерживать частоту появления новых постов в блоге на уровне хотя бы раз в неделю. Вечно всякие глупости в реале, вроде сессии, портят все планы :) Стиснув зубы, пишу очередной пост, стараясь, чтобы получилось интересно и полезно для читателей.

На всякий случай напоминаю, что mod_gzip – это модуль для веб-сервера Apache, предназначенный для сжатия трафика. Работает это очень просто – если модуль установлен, а браузер посетителя при запросе страницы говорит, что понимает сжатие gzip:

Accept-Encoding: gzip

то веб-сервер может послать ему не оригинал страницы, а ее сжатую с помощью gzip версию:

Content-Type: text/html; charset=utf-8
Content-Encoding: gzip

Файлы вроде .css или JavaScript, которые по идее никогда не меняются, достаточно сжать один раз – вручную, или заставить модуль кэшировать архивированные копии. Для тестирования модуля я рекомендую воспользоваться сервисом http://web-sniffer.net/

Веб сниффер

На самом деле в интернете довольно много примеров настройки сжатия трафика с помощью mod_gzip, но я столкнулся с некоторыми трудностями при его использовании, о которых хотел бы рассказать. Ниже идет мой конфигурационный файл (mod_gzip.conf), используемый для сжатия веб-трафика этого блога. Его можно подключить к httpd.conf (или что там у вашего хостера? у моего – virtual.conf.manual) с помощью директивы Include:

Include /full/path/to/mod_gzip.conf

Скачать текущую версию файла mod_gzip.conf можно здесь (784 байт, md5: 22af9d17c3de503596f46c2b162d9c12). А вот его код:

1
mod_gzip_on                   Yes

Пока все просто. Если модуль установлен, то включаем его.

3
4
5
mod_gzip_can_negotiate        Yes
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-сжатие. Таким образом мы можем заранее сжать все файлы, которые в последствии не собираемся редактировать, сэкономив тем самым немного процессорного времени.

6
mod_gzip_update_static        No

Если создавать руками сжатые копии файлов для предыдущих опций влом, можно поставить здесь Yes, загрузить нужные файлы (для них модулем будут созданы сжатые копии), а затем поставить обратно No. Сжатые копии перезаписываются при каждом новом обращении к файлам, пока здесь не будет прописан No.

7
8
mod_gzip_temp_dir             /tmp
mod_gzip_keep_workfiles       No

Тут можно сменить каталог для временных файлов и указать, требуется ли их хранить. Последнее может пригодиться для отладки.

9
10
11
mod_gzip_minimum_file_size    500
mod_gzip_maximum_file_size    500000
mod_gzip_maximum_inmem_size   60000

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

12
13
14
15
mod_gzip_min_http             1000
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-скриптами.

16
17
18
19
20
21
mod_gzip_item_include         mime       ^text/.*
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_item_include         mime       ^text/html$

То есть с долларом на конце, обозначающим (если вы подзабыли регулярные выражения) конец строки. Так вот оказывается, что это не всегда работает, в зависимости, судя по всему, от версии mod_gzip. Видимо это связано с тем, что веб-сервер передает значение Content-Type в таком виде:

Content-Type: text/html; charset=utf-8

То есть после text/html никакого конца строки на самом деле нет. Так-то ©.

22
mod_gzip_dechunk              Yes

Позволяет mod_gzip декодировать ответы сервера с

Transfer-encoding: chunked

Если вы не знаете, что это такое, то просто поверьте, что это действительно должно быть в конфиге. Todo: написать описание протокола HTTP и объяснить, что такое chunked.

23
24
LogFormat "%h %l %u %t \"%V %r\" %< Out:%{mod_gzip_output_size}n = %{mod_gzip_compression_ratio}n pct." common_with_mod_gzip_info2
CustomLog /full/path/to/logs/mod_gzip.log common_with_mod_gzip_info2

Формат записей в лог-файле и путь к лог-файлу. Логи следует включить только на время тестирования mod_gzip, потом они будут только зря занимать место на диске. Вот как примерно будут выглядеть записи в mod_gzip.log:

89.67.45.123 - - [14/Dec/2009:23:38:52 +0300] "eax.me GET /files/2009/10/select-dict.png HTTP/1.1" 200 14611 Content-Type: 'image/png' mod_gzip: DECLINED:EXCLUDED In:0 -< Out:0 = 0 pct.
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 их не сильно беспокоит (в отличии от числа запущенных процессов и объема потребляемой оперативной памяти), потому экономия со стороны вебмастера играет второстепенную роль.

PS. Мою статью Mutt, ssmtp и отправка отчетов опубликовали на Хабре! Правда, меня сильно беспокоит, что инвайтом никто не поделился в течение уже недели…

Уже удалили с Хабра. Ну раз она там никому не нужна, скоро опубликую в этом блоге.

Ну вот я и на Хабре. Решил опубликовать статью на нем. Читаем – Mutt, ssmtp и отправка отчетов.

Похожие посты:


  • http://sabini.ch vadim s. sabinich

    эм.. у меня тоже, но настроено в nginx, который стоит фронтендом к apache
    правда, у меня всего 4 строчки =)
    gzip on;
    gzip_proxied any;
    gzip_types application/xml application/x-javascript text/css application/json;
    gzip_http_version 1.0;

  • http://eax.me/ Безумный Программист

    Сам с nginx никогда не работал. Все хочу попробовать, да руки не доходят. А какие преимущества он дает при использовании в связке с апачем?

  • http://sabini.ch vadim s. sabinich

    если на пальцах: чтобы отдать по запросу какой-либо статический материал, апач форкает новый процесс. Если запросов много – много процессов апача и ОЗУ ограничено – сервер начинает плохо себя чувствовать.
    Если ставим тот же nginx, то он висит на 80 порту и принимает все запросы. если запросы идут на указанные в настройках статические файлики, то он отдает их сам и не форкается. остальное перенаправляется к apache. С точки зрения оптимизации появляется редирект, от которого никак не избавиться =)
    в место такой связки можно использовать что-нибудь типа mod_proxy и squid, к примеру. сам не пробовал

  • http://eax.me/ Безумный Программист

    >> С точки зрения оптимизации появляется редирект, от которого никак не избавиться =)

    В смысле 301 redirect или? Вместо fork создается новый поток или все происходит просто в одном процессе? Если так, то правильно ли я понимаю, что на сайтах с большим числом посетителей использовать nginx не следует из-за того, что он не будет успевать принимать соединения? Что посоветуете почитать по теме?

  • http://sabini.ch vadim s. sabinich

    ну вот кусок конфига nginx
    server {
    listen IP:80;
    server_name domain.ru http://www.domain.ru;
    location / {
    proxy_pass http://IP:8080;
    proxy_redirect http://IP:8080/ /; <== перенаправляется на apache
    == еще кучька строчек ==
    нет, с помощью nginx можно чертовски снизить нагрузку на сервер.
    Ну.. начни хотя бы с педивикии и там по ссылочкам.

  • http://eax.me/ Безумный Программист

    Спасибо! Буду изучать методы борьбы с 502 Bad Gateway :)

  • shutdownow

    Ставь апач 2.хх, там сжатие встроенное.

  • http://eax.me/ Безумный Программист

    Это знаете ли от хостера зависит, а не от меня. А в случае с OpenBSD еще и от ОС.

  • Artooha

    Ребята, может кто знает, в чем может быть проблема. Есть четыре сайта на одном и том же хостинге, один грузится нормально, остальные ну оочень тормозно. Если грузить Оперой Турбо (она на серваке своем данные сжимает и затем отправляет мне), то нормально. Пробовал в .htaccess сжатие прописать, не помогает. Из некоторых других городов тоже нормально. Склоняюсь думать, что дело в провайдере. Что это может быть? Вообще кто-нить пользовался услугами хостера justhost.com? Хотя о хостере ничего плохого сказать не могу, полтора года сидел там и все нормально было… И кому не в лом, зайдите на artooha.com и скажите, с нормальной ли скоростью загрузился

  • http://eax.me/ Безумный Программист

    У меня Ваш сайт нормально грузится.

blog comments powered by Disqus