Пересборка Nginx с поддержкой Brotli
Feb 6, 2017 21:07 · 513 words · 3 minute read
Мы уже знаем, как включить HTTP2.0 в Nginx и умеем собирать Nginx с поддержкой ALPN (Application-Layer Protocol Negotiation) для браузера Chrome.
Эта статья пригодится всем тем, кто неравнодушен к скорости доставки своего приложения пользователю, кто борется за миллисекунды и килобайты — давайте разберемся!
В двух словах: Brotli — алгоритм сжатия данных, основанный на более современном варианте алгоритма LZ77. Brotli был разработан и представлен компанией Google в 2015 году как специализированный алгоритм для сжатия веб-шрифтов. В дальнейшем была представлена версия brotli
, которая содержала улучшения направленные на сжатие всего интернет-трафика (HTML, CSS, JS). Поддержка данного алгоритма по умолчанию включена в Chrome 49+, Firefox 44+, Opera 36+ и мобильном Chrome. Больше информации и сравнение с остальными алгоритмами сжатия можно найти тут.
Примечание. Важное дополнение: так как brotli
несовместим с gzip
, он поддерживается только для HTTPS-ресурсов, чтобы всякие тупые прокси не побили контент.
Проверить поддержку brotli
клиентом легко: в заголовке запроса accept-encoding
должно быть br
(что означает brotli
), например так:
accept-encoding: gzip, deflate, sdch, br
На сегодняшний день официального модуля для поддержки Brotli в Nginx нет, поэтому будем все делать руками.
Сначала стоит определиться, как будем использовать brotli
: в статическом варианте (brotli_static
, файлы сжаты заранее и отдаются Nginx как есть) или в динамическом (brotli
, сжатие на лету). Собрать модуль в статическом режиме проще, поэтому мы рассмотрим сборку модуля для динамического режима работы.
Скачиваем и распаковываем исходники актуальной версии Nginx:
cd /opt/
wget https://nginx.org/download/nginx-1.11.9.tar.gz
tar xf nginx-1.11.9.tar.gz
Получаем код модуля ngx_brotli
:
git clone https://github.com/google/ngx_brotli.git
Далее выполняем:
cd /opt/ngx_brotli && git submodule update --init && cd /opt/nginx-1.11.9
иначе при сборке Nginx столкнемся с ошибкой:
...
adding module in /opt/ngx_brotli
./configure: error: Brotli library is missing from the /opt/ngx_brotli/deps/brotli directory.
...
Находясь в каталоге с исходниками Nginx собираем его (не забываем про поддержку APLN):
./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-file-aio \
--with-http_v2_module \
--with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' \
--with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed' \
--with-openssl=/opt/openssl-1.0.2j \
--add-module=/opt/ngx_brotli
make
make install
service nginx restart
Теперь, когда у нас собран Nginx с поддержкой brotli
, необходимо внести несколько изменений в конфигурационные файлы web-сервера. Если вы решили использовать brotli
в статическом режиме, то для его активации достаточно добавить одну директиву в секции http
конфига /etc/nginx/nginx.conf
:
...
brotli_static on;
...
Теперь Nginx будет искать версию файла с суффиксом .br
, если клиент поддерживает brotli
, а если не найдёт, то будет работать модуль gzip_static
(если включён).
В нашем случае brotli
используется в динамическом режиме (сжатие на лету), поэтому директив будет чуть больше:
...
brotli on; # включаем brotli
brotli_comp_level 6; # уровень компрессии от 1 до 11
brotli_types text/plain
text/css
text/xml
application/x-javascript; # MIME-типы контента для сжатия
...
Когда brotli
включен, он получает приоритет над gzip
, следовательно gzip
‘ом данные будут сжиматься только если браузер не поддерживает brotli
.
Проверить, все ли правильно сделано можно тут.