Статьи

Автор: lissyara
Опубликована: 25 января 2005, www.lissyara.su/?id=1131

mod_gzip — сжатие html страниц 'на лету'

Столкнулся с тем, что отчёты, которые делал sarg, на одной из удалённых машин очень уж большого размера — html-файлы были по мегабайту, по два... Линия там не очень толстая, да и до кучи время отклика очень большое 130 миллисекунд (что, к делу отношения не имеет — самое главное, что не толстая :))... Смотреть статистику было тяжело — файлы грузились подолгу (правда, раз загрузившись, кэшировались, и потому второй заход был шустрым). Подумавши, вспомнил, что давно, когда-то, «альфа-версия» этого сайта, ещё в html, висела на линии в 64k — и я откуда-то скачивал и компилил модуль для сжатия страниц «на лету», для apache1.3.x. Порывшись, выяснил — что существует по крайней мере два решения — mod_deflate — отечественное решение для apache1.3 — причём в apache2 уже свой модуль deflate, и mod_gzip. У обоих есть недостатки — у mod_deflate — то, что надо перекомпилить апачу, а у mod_gzip — он не сразу жмёт то, что выводится пользователю, а вначале сохраняет всё это во временных файл, а потом уже жмёт его и отдаёт посетителю... Кругом засада. Апач перебирать — лениво, да и нагрузка не какая-то безумная — я ж не хостер, поэтому решил снова поковыряться с mod_gzip. Кстати, он уже есть в портах, оттуда и ставим:

/usr/home/lissyara/>cd /usr/ports/
/usr/ports/>make search name='mod_gzip'
Port:   mod_gzip-1.3.26.1a
Path:   /usr/ports/www/mod_gzip
Info:   An Internet Content Acceleration module for Apache
Maint:  ale@FreeBSD.org
B-deps: apache-1.3.34_3 expat-1.95.8_3 perl-5.8.7_2
R-deps: apache-1.3.34_3 expat-1.95.8_3 perl-5.8.7_2
WWW:    http://sourceforge.net/projects/mod-gzip/

/usr/ports/>cd /usr/ports/www/mod_gzip
/usr/ports/www/mod_gzip/>make && make install && make clean

Если апач не стоит — он его за собой потащит, причём 1.3.x — ибо он именно под него, под apache2 он не нужен, как я уже говорил — там для сжатия есть штатные средства. Также надо отметить, что здесь я документации по нему не нащёл, хотя в портах стоит именно эта ссылка, зато на домашней странице нашлась вся необходимая инфа.

После установки раскомментируем следующие строки в конфиге апаче, находящиеся в секции модулей:

/usr/local/etc/apache/httpd.conf

#LoadModule gzip_module        libexec/apache/mod_gzip.so
#AddModule mod_gzip.c

А также добавим куда-нить в середину конфига такие строки:

<IfModule mod_gzip.c>
# включен ли модуль mod_gzip

mod_gzip_on                   Yes
# если положить в той же директории сжатый файл, 
# с таким же именем и указанным расширением
# (т.е. index.html и index.html.gz) то будет
# отдан сжатый файл,  а не сжиматься index.html
# удобно для экономии ресурсов CPU
mod_gzip_can_negotiate        Yes
# расширение сжатого файла (см. предыдущий пункт)

mod_gzip_static_suffix        .gz
AddEncoding              gzip .gz
# обновление сжатого файла. Если в директории лежит
# оригинальный файл, и сжатая версия (см. предыдущие
# три пункта) то при КАЖДОМ обращении к файлу,
# оригинал сжимается, и архивный вариант заменяется
# обновлённым. Наверно иногда и такое нужно :)
mod_gzip_update_static        No

# адрес, по которому можно посмотреть статус модуля mod_gzip
# на сервере - т.е. набираете адрес, типа
# http://www.site-name.ru/mod_gzip_status
# и видите - включен модуль или нет...
mod_gzip_command_version      '/mod_gzip_status'
# директория для временных файлов. Если не указана, то будет
# использовать дефолтовую - т.е. /tmp
mod_gzip_temp_dir             /tmp
# оставлять, или нет рабочие файла во временной директории - 
# если да, то он их оставляет. Надо заметить, что нужно это только

# для отладки, т.к. если оставить надолго этот пункт включенным,
# то место надиске может кончится :)
mod_gzip_keep_workfiles       No
# минимальный размер файла, который будет сжиматься.
# Если файл меньше этого размера, то он не сжимается.
# причина - сжатый часто оказывается больше исходного :)
mod_gzip_minimum_file_size    500
# максимальный размер файла который будет сжиматься. С очень большими

# файлами много времени уходит на сжатие, если машина слабая,
# или сильно загруженная - клиент может не дождаться...
# по дефолту тут было полмега - на мой взгляд, для моих условий 
# использования, неоправданно мало. Я увеличил до 5 мег.
mod_gzip_maximum_file_size    5000000
# максимальный размер файла, сжимаемого непосредственно в памяти
# - если файл большего рамера, то будет использоваться
# временный файл. Если версия mod_gzip больше 1.3.19.x 

# то если написано значение больше 60000 оно будет автоматически
# снижено до 60000 - связано с ограничениями некоторых ОС
# (а на мой взгляд, лучше б научили его зазбираться под какой ОС
# он работает, а не рубить все сразу...)
mod_gzip_maximum_inmem_size   60000
# минимальная версия протокола http поддерживаемая клиентом,
# начиная с которой будет работать mod_gzip
# 1000 = HTTP/1.0, 1001 = HTTP/1.1, и т.п.

mod_gzip_min_http             1000
# методы запроса, для которых будет работать mod_gzip
# аффтар рекомендует отключать POST в случае проблем
mod_gzip_handle_methods       GET POST
# исключения - версии браузеров, не умеющих коректно
# разбирать заголовки, или проводить декомпрессию
mod_gzip_item_exclude         reqheader  "User-agent: Mozilla/4.0[678]"

# То, что будет сжиматься - файлы с расширением .html
mod_gzip_item_include         file       \.html$
# исключения - ява скрипты и таблицы стилей.
# на самом деле современные браузеры корректно понимают
# сжатые скрипты и CSS - тока Netscape4 не переваривает
# но его немного - поэтому в принципе эти две строки можно
# закомментировать, или поменять `exclude` на `include`
mod_gzip_item_exclude         file       \.js$
mod_gzip_item_exclude         file       \.css$

# сжимаем всё с расширением .pl - это либо CGI-скрипты,
# вывод которых - html (если они у Вас выводят графику или ещё
# что-то подобное, надо закомментировать строку), либо просто
# скрипт не в директории /cgi-bin/ который будет показан как
# текст - так что надо жать.
mod_gzip_item_include         file       \.pl$
# жмём вывод всех скриптов
mod_gzip_item_include         handler    ^cgi-script$

# жмём всё, что apache посчитал текстом (собстно html`ки,
# листинг директорий, текстовые файлы....)
mod_gzip_item_include         mime       ^text/html$
mod_gzip_item_include         mime       ^text/plain$
mod_gzip_item_include         mime       ^httpd/unix-directory$
# не жмём картинки (толку-то... либо ничё не выиграешь,
# либо выигрыш мизерный - 1-2% да ещё и не все браузеры
# сжатые рисунки понимают.)
mod_gzip_item_exclude         mime       ^image/
# разрешить mod_gzip удалять заголовок 'Transfer-encoding: chunked'
# и отдавать страницу одним куском (некоторые скрипты отдают кусками)
mod_gzip_dechunk              Yes

# формат логов, если хотите, чтобы в них отображалось - была ли сжата
# страница, процент сжатия, исходный и сжатый размер...
# в одну строку оно у меня не влезло - пришлось перенести на 4 строчки
# если будуте копировать отсюда - уберите обратные слэши в конце
# каждой строки и сделайте снова одной строкой.
# P.S. :) Сам же скопировал и вставил - всё пучком, апач понимает
# и с экранированными переносами - можно как есть всё втыкать - работает
LogFormat                     "%h %l %u %t \"%V %r\" %<s %b \
mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n -< \

Out:%{mod_gzip_output_size}n = %{mod_gzip_compression_ratio}n \
pct." common_with_mod_gzip_info2
# куда класть лог с процентами сжатия & etc (см. предыдущий пункт)
CustomLog                     /var/log/mod_gzip.log common_with_mod_gzip_info2
# Непонял этот пункт - какой-то счётчик заголовков (размера заголовков)
# отданных сервером... Что считает, зачем... По дефолту считает - 
# ну и пусть считает...
mod_gzip_add_header_count     Yes

# посылать какой-то 'Vary' http хеадер.
# советуют не трогать, если не уверены в том, что делаете...
mod_gzip_send_vary            On
</IfModule>

У меня апач на тестовой машине не стоял, поэтому надо добавить строку в /etc/rc.conf, и запустить его. Если у Вас стоял — то только перезапустить:

/usr/local/etc/apache/>echo '' >> /etc/rc.conf
/usr/local/etc/apache/>echo 'apache_enable="YES"' >> /etc/rc.conf
/usr/local/etc/apache/>../rc.d/apache.sh restart
apache not running? (check /var/run/httpd.pid).
Starting apache.
/usr/local/etc/apache/>ps -ax | grep httpd

83313  ??  Ss     0:00.08 /usr/local/sbin/httpd
83314  ??  S      0:00.00 /usr/local/sbin/httpd

83315  ??  S      0:00.00 /usr/local/sbin/httpd
83316  ??  S      0:00.00 /usr/local/sbin/httpd

83317  ??  S      0:00.00 /usr/local/sbin/httpd
83318  ??  S      0:00.00 /usr/local/sbin/httpd

83320  p0  S+     0:00.01 grep httpd

Всё взлетело. Смотрим логи (предварительно я закинул туда несколько крупных html файлов):

192.168.20.141 - - [25/Jan/2006:15:22:10 +0300] "FreeBSD6 GET / HTTP/1.1"
    200 2038 mod_gzip: SEND_AS_IS:RESPONSE_CONTENT_TYPE_EXCLUDED In:0 -< Out:0 = 0 pct.
192.168.20.141 - - [25/Jan/2006:15:22:16 +0300] "FreeBSD6 GET /stat/ HTTP/1.1"
    200 644 mod_gzip: DECHUNK:OK In:1013 -< Out:404 = 61 pct.
192.168.20.141 - - [25/Jan/2006:15:22:29 +0300] "FreeBSD6 GET /stat/192.168.20.53/ HTTP/1.1"
    200 15001 mod_gzip: DECHUNK:OK In:209592 -< Out:14759 = 93 pct.
192.168.20.141 - - [25/Jan/2006:15:22:36 +0300]
    "FreeBSD6 GET /stat/192.168.20.53/192.168.20.53.html HTTP/1.1"
	200 58145 mod_gzip: OK In:684499 -< Out:57805 = 92 pct.

192.168.20.141 - - [25/Jan/2006:15:22:52 +0300]
    "FreeBSD6 GET /stat/192.168.20.53/d192.168.20.53.html HTTP/1.1"
	200 2713 mod_gzip: OK In:20669 -< Out:2375 = 89 pct.
192.168.20.141 - - [25/Jan/2006:15:22:58 +0300]
    "FreeBSD6 GET /stat/192.168.20.53/tt192.168.20.53-205_188_248_199.html HTTP/1.1"
	200 1504 mod_gzip: OK In:9921 -< Out:1166 = 89 pct.
192.168.20.141 - - [25/Jan/2006:15:23:09 +0300] "FreeBSD6 GET /stat/192.168.20.53/?S=A HTTP/1.1"
	200 16592 mod_gzip: DECHUNK:OK In:209592 -< Out:16350 = 93 pct.
192.168.20.141 - - [25/Jan/2006:15:23:14 +0300]
    "FreeBSD6 GET /stat/192.168.20.53/tt192.168.20.53-au_download_windowsupdate_com.html HTTP/1.1"
	200 9591 mod_gzip: OK In:300591 -< Out:9252 = 97 pct.
192.168.20.141 - - [25/Jan/2006:15:23:17 +0300]
    "FreeBSD6 GET /stat/192.168.20.53/tt192.168.20.53-counter_rambler_ru.html HTTP/1.1"
	200 5691 mod_gzip: OK In:105310 -< Out:5352 = 95 pct.

192.168.20.141 - - [25/Jan/2006:15:23:28 +0300] "FreeBSD6 GET /stat/ HTTP/1.1"
    200 644 mod_gzip: DECHUNK:OK In:1013 -< Out:404 = 61 pct.
192.168.20.141 - - [25/Jan/2006:15:23:32 +0300] "FreeBSD6 GET /stat/192.168.20.46/ HTTP/1.1"
    200 18004 mod_gzip: DECHUNK:OK In:267673 -< Out:17762 = 94 pct.
192.168.20.141 - - [25/Jan/2006:15:23:34 +0300]
    "FreeBSD6 GET /stat/192.168.20.46/192.168.20.46.html HTTP/1.1"
	200 71697 mod_gzip: OK In:873228 -< Out:71357 = 92 pct.
192.168.20.141 - - [25/Jan/2006:15:23:44 +0300]
    "FreeBSD6 GET /stat/192.168.20.46/d192.168.20.46.html HTTP/1.1"
	200 2728 mod_gzip: OK In:20695 -< Out:2390 = 89 pct.
192.168.20.141 - - [25/Jan/2006:15:23:48 +0300] "FreeBSD6 GET /stat/192.168.20.42/ HTTP/1.1"
    200 19603 mod_gzip: DECHUNK:OK In:278720 -< Out:19361 = 94 pct.

192.168.20.141 - - [25/Jan/2006:15:23:49 +0300]
    "FreeBSD6 GET /stat/192.168.20.42/192.168.20.42.html HTTP/1.1"
	200 76139 mod_gzip: OK In:910830 -< Out:75799 = 92 pct.
192.168.20.141 - - [25/Jan/2006:15:23:54 +0300]
    "FreeBSD6 GET /stat/192.168.20.42/d192.168.20.42.html HTTP/1.1"
	200 2576 mod_gzip: OK In:20530 -< Out:2238 = 90 pct.
192.168.20.141 - - [25/Jan/2006:15:23:59 +0300] "FreeBSD6 GET /stat/192.168.20.35/ HTTP/1.1"
    200 8649 mod_gzip: DECHUNK:OK In:116350 -< Out:8408 = 93 pct.
192.168.20.141 - - [25/Jan/2006:15:24:01 +0300]
    "FreeBSD6 GET /stat/192.168.20.35/192.168.20.35.html HTTP/1.1"
	200 32191 mod_gzip: OK In:380065 -< Out:31851 = 92 pct.
192.168.20.141 - - [25/Jan/2006:15:24:05 +0300]
    "FreeBSD6 GET /stat/192.168.20.35/tt192.168.20.35-36k_ru.html HTTP/1.1"
	200 1234 mod_gzip: OK In:3154 -< Out:898 = 72 pct.

192.168.20.141 - - [25/Jan/2006:15:24:07 +0300]
    "FreeBSD6 GET /stat/192.168.20.35/tt192.168.20.35-459109_banners_zbs_ru.html HTTP/1.1"
	200 1253 mod_gzip: OK In:3284 -< Out:917 = 73 pct.
192.168.20.141 - - [25/Jan/2006:15:24:09 +0300]
    "FreeBSD6 GET /stat/192.168.20.35/tt192.168.20.35-534083_banners_zbs_ru.html HTTP/1.1"
	200 1246 mod_gzip: OK In:3169 -< Out:910 = 72 pct.

Что ж — процент сжатия хороший, тормозов я не заметил (тестовая машина — P-II, 350MHz, 64 RAM) — больше у моего браузера времени уходило на вывод страницы, чем на сжатие у фряхи. А по адресу http://192.168.20.100/mod_gzip_status я увидел следующий текст:

mod_gzip is available...
mod_gzip_version = 1.3.26.1a
mod_gzip_on = Yes

Данный модуль, на мой взгляд, пригодится тем, у кого не очень быстрый канал, и при этом избыток ресурсов на машине которая торчит в инет... Прям как у меня на некоторых машинах :)