Опубликован: 16.06.2010 | Доступ: свободный | Студентов: 2352 / 93 | Оценка: 4.39 / 4.00 | Длительность: 17:32:00
ISBN: 978-5-9963-0253-6
Лекция 3:

Алгоритмизация сжатия текстовых файлов

< Лекция 2 || Лекция 3: 123 || Лекция 4 >

2.3. Настройка веб-серверов Apache, nginx и lighttpd

Существуют два разных подхода к использованию сжатия на стороне сервера: сжимать данные "на лету" и использовать предварительно сжатые файлы. Первый выгоднее с точки зрения актуализации: не нужно заботиться, не устарел ли тот или иной файл; второй метод экономнее обходится с ресурсами машины, но приходится держать две копии файла для тех браузеров, которые не поддерживают сжатие или поддерживают его с ошибками.

К счастью, методы можно успешно комбинировать, что позволяет сочетать достоинства того и другого.

2.3.1. Apache

Для Apache 1.x существуют два модуля, осуществляющих сжатие контента: это mod_deflate и mod_gzip. Оба модуля разработаны сторонними разработчиками. Первый представляет собой патч к исходному коду вебсервера, что иногда бывает неудобно и не умеет отдавать статически сжатые файлы; второй обладает другими недостатками: сначала сохраняет ответ во временный файл, который потом сжимает и отдает, что сказывается на производительности, и помимо этого конфигурационные опции модуля довольно аскетичны.

В Apache 2.x "из коробки" входит модуль mod_deflate (которые не имеет ничего общего с модулем для Apache 1.x).

Если есть возможность, настоятельно рекомендуем использовать для Apache 1.x модуль mod_deflate, он позволяет более тонко обходить ошибки браузера, имеет настройки степени сжатия плюс обладает лучшей производительностью. Ниже приведен оптимальный, на наш взгляд, конфигурационный файл этого модуля.

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

# Apache 1.x mod_deflate (необходим mod_setenvif)
# включаем модуль
DeflateEnable on
# включаем обход ошибки Internet Explorer 4.0, связанной с докачкой
# сжатого контента
DeflateDisableRange "MSIE 4."
# на данный момент все прокси корректно обрабатывают сжатый
# ответ, поэтому мы включаем сжатие, даже если использован
# прокси
DeflateHTTP 1.0
# сжиматься будут только ответы, не кэшируемые прокси-серверами, это
# позволяет избежать проблем с WinRoute, Kerio WinRoute и другими
DeflateProxied poor_cachable
# эта директива включает заголовок Vary для всех ответов,
# IE версий 4.0—6.0SP1 не кэшируют ответы, если сжатие выключено,
# но получен заголовок Vary, но эти версии сейчас используются
# очень мало
DeflateVary on
# уровень сжатия — максимальный
DeflateCompLevel 9
DeflateHash 128
DeflateWindow 32
# включаем игнорирование вызова ap_bflush, это улучшает сжатие
# ответов некоторых приложений (например, написанных
# с применением Chili!Soft ASP). Если ваше приложение намеренно
# вызывает этот метод, опцию лучше отключить
DeflateIgnoreFlush on
# минимальный размер, при котором ответ сервера будет сжиматься
DeflateMinLength 100
# настраиваем, что сжимать
DeflateType text/html text/css text/xml application/xml image/x-icon
DeflateType application/x-javascript text/plain
# исключаем проблемные случаи по умолчанию выключаем сжатие
# на CSS и JavaScript (оно будет разрешено
# ниже для браузеров, не имеющих проблем, специальный флаг "no_gzip"
# говорит модулю, что сжатие надо выключить)
SetEnvIf Content-Type text/css no_gzip
SetEnvIf Content-Type application/x-javascript no_gzip
SetEnvIf Content-Type image/x-icon no_gzip

# выключаем сжатие для MSIE < 6SP1,
# исключаем притворяющуюся IE "Оперу"
BrowserMatch "MSIE [456]" no_gzip
BrowserMatch "SV1;" !no_gzip
BrowserMatch "Opera" !no_gzip
BrowserMatch "MSIE ([789]| [1-9][0-9])" !no_gzip
# не имеет проблем Firefox > 3
BrowserMatch "Firefox/(3\.[^0]|[4-9]|[1-9][0-9])" !no_gzip

Образец конфигурационного файла модуля mod_gzip взят из книги "Разгони свой сайт", в данной редакции комментарии были несколько расширены, а в настройку внесены правки.

Уровень эффективности сжатия не регулируется настройками модуля и может быть изменен только правкой исходного кода (строка gz1-level = 6 в функции gz1_init ).

Упомянутый недостаток mod_gzip — недостаточно гибкие опции кон- фигурирования не дают выборочно включить сжатие CSS и JS только в тех браузерах, где это не создает проблем. По этой причине сжатие таких файлов отключено в данной конфигурации.

# Apache 1.x mod_gzip
<IfModule mod_gzip.c="">
# включаем gzip
mod_gzip_on Yes

# если рядом с запрашиваемым файлом есть сжатая версия
# с расширением .gz, то будет отдана именно она, ресурсы CPU
# расходоваться не будут
mod_gzip_can_negotiate Yes

# используем при статическом архивировании расширение .gz
mod_gzip_static_suffix .gz

# выставляем для статически архивированных файлов
# заголовок Content-Encoding: gzip
AddEncoding gzip .gz

# не обновлять самостоятельно статически архивированные файлы,
# при включении этой опции вам не нужно самостоятельно проверять
# актуальность сжатых данных, но нужно позаботиться о том,
# что процесс веб-сервера имел доступ на запись к сжатым файлам
mod_gzip_update_static No

# выставляем минимальный размер для сжимаемого файла, файлы
# меньшего размера сжимать неэффективно:
mod_gzip_minimum_file_size 1000

# и максимальный размер файла, слишком большие файлы будут
# сжиматься очень долго, поскольку mod_gzip не умеет сжимать
# данные по мере их получения, то пользователь начнет получать
# файл с задержкой, только после того как он будет полность сжат
mod_gzip_maximum_file_size 500000

# выставляем максимальный размер файла, сжимаемого прямо
# в памяти, чем больше эта величина, тем больше производительность
# и тем больше расход памяти каждый процессом, 60000 — максимальное
# значение для этой величины, поскольку авторы модуля столкнулись
# с проблемами при выделении более чем 64КБ в некоторых
# операционных системах
mod_gzip_maximum_inmem_size 60000

# устанавливаем версию протокола, с которой будут отдаваться
# gzip-файлы на клиент. Настройка появилась в те времена, когда
# некоторые прокси неверно обрабатывали сжатый ответ. В версии 1.1
# протокола HTTP прокси обязан выставить заголовок Via,
# что позволяет определить, проходит ли запрос через прокси,
# в версии 1.0 такого заголовка нет, поэтому в те времена
# запросы версии 1.0 просто не сжимались
mod_gzip_min_http 1000

# исключаем известные проблемные случаи (IE до 6.0SP1)
# вообще-то старые версии Opera также содержат строку MSIE,
# но мы их отделять не будем, поскольку в Apache используется
# синтаксис POSIX Extended Regular Expression, а записать
# на этом языке два исключения в одном правиле невероятно трудно.
# Правило, которое записано ниже, может давать ложные срабатывания
# в некоторых ситуациях, но в реальности эти ситуации не встречаются
mod_gzip_item_exclude reqheader "User-agent: MSIE [456]([^S]V|[^S]V1|[^V]1|1[^;]|SV[^1]|[^SV1])+$"
# устанавливаем сжатие по умолчанию для файлов .html
mod_gzip_item_include file \.html$

# дополнительно сжимаем другие текстовые файлы с указанными
# MIME-типами
mod_gzip_item_include mime ^text/html$
mod_gzip_item_include mime ^text/plain$
mod_gzip_item_include mime ^httpd/unix-directory$

# отключаем сжатие для картинок (не дает никакого эффекта)
mod_gzip_item_exclude mime ^image/

# отключаем 'Transfer-encoding: chunked' для gzip-файлов, чтобы
# страница уходила на клиент одним куском
mod_gzip_dechunk Yes
# добавляем заголовок Vary для корректного распознавания браузеров,
# находящихся за локальными прокси-серверами
mod_gzip_send_vary On
</IfModule>

<IfModule mod_headers.c>
# запрещаем прокси-серверам кэшировать у себя сжатые версии файлов
  <FilesMatch .*\.(html|txt)$>
    Header set Cache-Control: private
  </FilesMatch>
</IfModule>

Модуль для Apache 2.x, mod_deflate, по настройкам схож со своим более ранним тезкой. Отличия: нет некоторых опций, которые вряд ли мо гут быть названы сейчас актуальными, и разделение сжатия HTML-файлов и файлов CSS/JS сделано удобнее.

Исходная версия конфигурационного файла этого модуля, опять же, взята из книги "Разгони свой сайт", здесь файл приводится с правками и расширенными комментариями.

Для управления этим модулем, как и в случае первого Apache, необходим mod_setenvif, следует учитывать, что часть настроек этого модуля mod_deflate нельзя использовать внутри файлов .htaccess, только внутри virtual host или на уровне глобальных настроек.

# Apache 2.x mod_deflate (необходим mod_setenvif)
# с самого начала включаем gzip для текстовых файлов
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml

# и для favicon.ico
AddOutputFilterByType DEFLATE image/x-icon

# также для CSS- и JavaScript-файлов
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/x-javascript

# далее устанавливаем максимальную степень сжатия (9)
# и максимальный размер окна (15). Если сервер не очень мощный,
# то уровень сжатия можно выставить в 1, размер файлов при этом
# увеличивается примерно на 20%.

DeflateCompressionLevel 9
DeflateWindowSize 15
DeflateBufferSize 32768

# отключаем сжатие для тех браузеров, у которых проблемы
# с его распознаванием

# выключаем сжатие для MSIE < 6SP1, исключаем
# притворяющуюся IE "Оперу"
BrowserMatch "MSIE [456]" no_gzip dont-vary
BrowserMatch "SV1;" !no_gzip !dont-vary
BrowserMatch "Opera" !no_gzip !dont-vary
# Firefox < 3.5, проблемы с CSS/JS
BrowserMatch "Firefox/[0-3]\." gzip-only-text/html
BrowserMatch "Firefox/3\.[1-9]" !gzip-only-text/html

# Chrome
BrowserMatch "Chrome/2" gzip-only-text/html

# все версии Safari
BrowserMatch "Safari" gzip-only-text/html

# Konqueror
BrowserMatch "Konqueror" gzip-only-text/html

# указываем прокси-серверам передавать заголовок User-Agent для
# корректного распознавания сжатия
Header append Vary User-Agent env=!dont-vary

# запрещаем кэширование на уровне прокси-сервера для всех файлов,
# для которых у нас выставлено сжатие,
<FilesMatch .*\.(css|js|php|phtml|shtml|html|xml="")$>
  Header append Cache-Control: private
</FilesMatch>

2.3.2. nginx

Достаточно популярный веб-сервер nginx (читается как "engine X") также имеет два модуля для управления сжатием: ngx_http_gzip_module для сжатия "на лету" и ngx_http_gzip_static_module для статически сжатых файлов.

# nginx, ngx_http_gzip_module и ngx_http_gzip_static_module
# включаем сжатие "на лету"
gzip on;

# типы файлов, который будут сжиматься, text/html указывать не нужно,
# этот тип сжимается по умолчанию
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/rss+xml text/javascript image/x-icon;

# минимальный размер сжимаемого контента
gzip_min_length 1000;

# максимальное сжатие
gzip_comp_level 9;

# минимальная версия протокола HTTP в запросе, при которой будет
# происходить сжатие
gzip_http_version 1.0;

# разрешает выдачу заголовка Vary
gzip_vary on;

# разрешить сжатие проксируемых ответов, у которых есть
# заголовки
# Expired, Cache-contol: no-cache, Cache-contol: no-store,
# Cache-contol: private или Authorization
gzip_proxied expired no-cache no-store private auth;

# отключаем сжатие для MSIE < 6.0SP1, с версии 0.8.11 эта маска
# не включает Internet Explorer 6.0SP2
gzip_disable msie6;

# к сожалению, у nginx нет способа запретить сжатие ответов
# какого-либо типа для обхода проблем в браузерах, но если
# у вас все файлы CSS и JavaScript оканчиваются, соответственно,
# на .css и .js, то можно ограничить их сжатие следующим способом
location ~* \.(css|js) {
  # разрешаем отдавать вместо несжатого файла предварительно
  # сжатый с постфиксом ".gz", если такой есть
  gzip_static on;
  # запрещаем сжатие файлов CSS и JS для проблемных браузеров
  gzip_disable Firefox/([0-2]\.|3\.0);
  gzip_disable Chrome/2;
  gzip_disable Safari;
}

2.3.3. lighttpd

У веб-сервера lighttpd (lighty) также имеются модули (modcom-press, moddeflate), поддерживающие сжатие контента. Причем поддерживаются не только методы gzip и deflate, но и bzip2, не рекомендуемый на данный момент из-за проблем совместимости с прокси-серверами.

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

Имя файла и его путь в кэше составляется из пути и имени запрашиваемого файла плюс имя метода сжатия и ETag. Соответственно, если меняется ETag, сервер создает файл с д ругим именем и отдает свежую копию.

Очистка кэша оставлена на усмотрение пользователя и может производиться, например, такой вот командой (удаление файлов, которые были модифицированы более 10 дней назад):

find /var/www/cache -type f -mtime +10 | xargs -r rm

По сравнению с остальными рассматриваемыми модулями mod_com-press имеет очень мало возможностей для конфигурирования. Оптимизированный конфигурационный файл приведен ниже.

# Lighttpd, mod_compress
# включаем сжатие
server.modules += ("mod_compress")

# включаем методы, которые будем поддерживать,
# здесь не указан bzip2
# из-за проблем с прокси и deflate из-за проблем с Konqueror
compress.allowed-encodings = ("gzip")

# директорий, куда складываются кэшированные пресжатые файлы
compress.cache-dir = "/var/www/cache/"

compress.filetype = ("text/plain", "text/html", "text/xml", "application/xml", "application/rss+xml", "image/x-icon")

# не сжимать контент, размер которого больше, чем 500KiB
compress.max-filesize = 500000

# боремся с проблемами в браузерах, основываясь на URL
$HTTP["url"] =~ "\.(css|js)$" {
  $HTTP["useragent"] != "Firefox/([0-2]\.|3\.0)" {
    $HTTP["useragent"] != "Chrome/2|Konqueror" {
    compress.filetype += ("text/css", "application/ 
    x-javascript", "application/javascript", 
    "text/javascript")
    }
  }
}
$HTTP["useragent"] = ~ "MSIE [4-6]" {
  $HTTP["useragent"] != "SV1|Opera" {
    compress.filetype = ()
  }
}

Модуль mod_deflate, который доступен в версии 1.5.0 и выше (или как патч к версии 1.4.x), предназначен для сжатия контента "на лету".

# Lighttpd, mod_deflate
# включаем сжатие
server.modules += ("mod_deflate")
deflate.enabled = "enable"

# максимальное сжатие
deflate.compression-level = 9
deflate.mem-level = 9
deflate.window-size = 15

# включаем методы, которые будем поддерживать, здесь не указан
# bzip2 из-за проблем с прокси и deflate из-за проблем с Konqueror
deflate.allowed_encodings = ("gzip")

# минимальный размер ответа, который будем сжимать

deflate.min-compress-size = 1000
# из-за того, что в зависимости от браузера мы не может отключать
# сжатие JS и CSS, не включаем их сжатие вообще
deflate.mimetypes = ("text/plain", "text/html", "text/xml", "application/xml", "application/rss+xml", "image/x-icon")

# минимальный размер блока для сжатия
deflate.work-block-size = 512

# отключаем сжатие для старых IE
$HTTP["useragent"] = ~ "MSIE [4-6]" {
  $HTTP["useragent"] != "SV1|Opera" {
    deflate.enabled = "disable"
  }
}
# боремся с проблемами в браузерах, основываясь на URL
$HTTP["url"] = ~ "\.(css|js)$" {
  $HTTP["useragent"] != "Firefox/([0-2]\.|3\.0)" {
    $HTTP["useragent"] != "Chrome/2|Konqueror|Safari" {
      compress.filetype += ("text/css", "application/x-javascript", "application/javascript", "text/javascript")
    }
  }
}
< Лекция 2 || Лекция 3: 123 || Лекция 4 >
Ольга Артёмова
Ольга Артёмова

Доброго времени суток!

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

Сертификация: оптимизация и продвижение web-сайтов.

Владимир Захов
Владимир Захов
Россия, СПБ