
Возможно, вы уже читали в новостях, что накануне Дня космонавтики вышел новый стабильный выпуск Angie 1.9.0, форка nginx, который продолжает развивать команда бывших разработчиков nginx. С интервалом примерно в квартал мы стараемся выпускать новые стабильные версии и радовать пользователей множеством улучшений. Данный релиз не стал исключением, но одно дело читать сухой лог изменений, а совсем другое познакомиться с функциональностью подробнее, узнать, как и в каких случаях её можно применить.
Список нововведений, на которых мы остановимся подробнее:
Сохранение зон разделяемой памяти с индексом кэша на диск;
Персистентный переход на резервную группу проксируемых серверов;
0-RTT в потоковом модуле;
Новый статус
busy
у проксируемых серверов во встроенном API статистики;Улучшения ACME‑модуля, позволяющего автоматически получать TLS‑сертификаты Let's Encrypt и др.;
Кэширование TLS‑сертификатов при использовании переменных.
За одним исключением, всё это вошло в состав свежей open source версии Angie и доступно прямо сейчас в наших репозиториях.
А кроме того, коротко предвосхищу ожидания от будущей версии Angie 1.10, которая должна появиться на свет где‑то уже в конце июня — начале июля.
Сохранение зоны разделяемой памяти с индексом кэша на диск
Одним из самых интересных нововведений свежего релиза 1.9 является возможность сохранить зону разделяемой памяти, которая хранит индекс кэша, на диск.
Для этого в директиве proxy_cache_path
помимо имени и размера зоны, теперь можно задать путь к файлу:
proxy_cache_path my_cache keys_zone=my_czone:256m:file=/path/to/my_cache.zone;
При завершении работы все данные из зоны будут выгружены в файл, а при запуске — загружены обратно из файла в разделяемую память.
Что это дает? Ранее, для подгрузки кэша после перезапуска сервера, использовался специальный процесс, т. н. загрузчик кэша (cache loader). Он обходил все файлы в директории кэша и загружал метаинформацию в индекс, который хранится в разделяемой памяти. Когда файлов очень много, то этот процесс может занимать минуты, часы и даже сутки, при этом создавая дополнительную, порой ощутимую нагрузку на жесткий диск. Кстати, в нашем мониторинге можно наблюдать за этим процессом: когда кэш ещё не перегружен, то значение поля cold
будет true
. Включать такой сервер в работу возможно не во всех случаях, иногда это может увеличивать задержки до неприемлемого уровня. В результате после перезапуска сервера приходится ждать все это время, прежде чем вернуть сервер в строй.
Но если индекс, который хранит разделяемая память, сохранен на диске в виде одного файла, то в отличие от минут, часов и порой даже суток, процесс загрузки этого файла в память занимает считанные мгновения. Таким образом, подргузка кэша с помощью процесса «cache loader» не требуется и на сервер можно пускать трафик сразу после запуска Angie.
Кстати, сохраненный индекс вместе с кэшом может быть перенесен на другой сервер, при условии совпадения архитектур и параметров сборок.
В будущих релизах мы планируем добавить сохранение зон разделяемой памяти и в остальные модули.
Персистентный переход на резервную группу проксируемых серверов (только PRO)
Другая интересная возможность, которая была добавлена, но на этот раз только в версию PRO, касается HTTP‑балансировщика. Новая директива backup_switch
теперь позволяет менять логику переключения на резервную группу серверов:
upstream backend {
zone backend 1m;
backup_switch permanent=5m;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backup1.example.com backup;
server backup2.example.com backup;
server backup3.example.com backup;
}
По умолчанию Angie для каждого поступающего запроса сперва пытается найти живой сервер в основной группе (без опции backup
) и если среди них живых серверов нет, то далее осуществляет поиск среди backup
‑группы. Таким образом, как только один из серверов в основной группе станет доступны, то на него сразу же будет направлен весь последующий трафик. В ряде конфигураций такое поведение не является приемлемым и в случае переключения на резервную группу требуется продолжать балансировать запросы на неё. Именно такой режим включает директива:backup_switch permanent;
В этом случае однажды столкнувшись с тем, что в основной группе нет живых серверов, Angie переключится на резервную группу и продолжит балансировать на неё трафик до тех пор, пока в резервной группе есть живые сервера или не произойдет перезагрузки конфигурации.
Если в опции permanent
задан таймаут, например, permanent=5m
, то попытки выбрать сервер в основной группе будут происходить, но не чаще, чем раз в заданный интервал. В случае успеха такой попытки — произойдет переключение обратно на основную группу. Такой режим является компромиссными и убережет от слишком частых переключений между резервной и основной группой в случае, если такое переключение все же требуется, но сервера в основной группе сохраняют нестабильность или остаются быть перегруженными.
Кроме этого в API статистики появился новый объект backup_switch
, который содержит числовое поле active
. Этот объект доступен только когда включен режим backup_switch permanent
. Поле active
отображает текущую активную группу: 0, если активная основная группа и 1 в случае backup
. В расширенной версии балансировщика Angie ADC резервных групп можно задать больше 1, поэтому и значение поля active
в этом случае может быть >1.
Если опция задана с интервалом времени (например, permanent=1m
), то при переключении на резервную группу в объекте backup_switch
также появляется поле timeout
, которое содержит число миллисекунд до очередной попытки переключиться на основную группу.
В будущих версиях планируем реализовать возможность настройки ещё более сложной логики переключения между резервными группами (например по количеству доступных серверов в группе, нагрузке на них и т. д.), а также новый интерфейс в API, который позволит принудительно переключать группы по команде извне.
Далее о более простых, но полезных функциях, которые были реализованы, как в open source версии, так и в PRO.
0-RTT в потоковом модуле
В потоковый модуль stream
добавили возможность использовать механизм TLS 1.3 Early Data (0-RTT), который ранее был доступен только в HTTP-модуле. Включается такой же директивой:
ssl_early_data on;
Данный механизм позволяет клиенту отправить данные до завершения стадии согласования соединения TLSv1.3, что сокращает задержку от момента подключения до момента обработки данных при терминации TLS. Но следует иметь в виду, что этот механизм уязвим к т.н. атакам повторного воспроизведения (replay), поэтому включать его можно только в случае, если сам веб-сервис или протокол, который проксируется через потоковый модуль, защищены от атак подобного рода.
Новый статус "busy" у проксируемых серверов
Следующее нововведение — это новый статус busy
, который может отображаться в поле state
у проксируемых серверов в нашем API статистики. Данный статус можно увидеть только в том случае, если в конфигурации сервера в upstream‑группе настроено ограничение max_conns
:server
backend.example.com:80
max_conns=128;
Как не трудно догадаться, если сервер уперся в ограничение по соединениям, то state
у него сменится на busy
до того момента, пока число соединений не опустится ниже лимита (либо он выключится и перейдет в один из других режимов down
/unhealthy
/unavailable
). Ранее, вместо busy
, сервер оставался в статусе up
, пока был живым, однако запросы на него направляться не могли из‑за ограничения max_conns
. Поэтому для лучшей индикации этого состояния и причин, по которым новые запросы не направляются на сервер — был добавлен дополнительный статус.
Доработки ACME-модуля
Следующая группа улучшений связана с дальнейшим развитием функциональности по автоматическому выпуску сертификатов ACME. Служат они для улучшения пользовательского опыта с данным модулем и были разработаны на основе обратной связи от нашего сообщества в Telegram.
В acme_client
добавлен новый параметр renew_on_load
, который позволяет гораздо проще принудительно запустить процесс перевыпуска сертификатов при загрузке конфигурации, если вдруг это зачем‑то потребовалось (например, стало известно об утечке ключей).
Также поменялся режим работы опции enabled=off
. Он стал более удобным в использовании и теперь позволяет временно отключить перевыпуск сертификатов, но если ранее они были уже выпущены, то доступ к ним сохраняется и их можно продолжать использовать в конфигурации.
В новой версии также был пересмотрен подход к валидации конфигурации ACME директив. Ранее директивы acme_client
требовали обязательного наличия минимум одной директивы acme
в блоках server
, что было не всегда удобно. Часто пользователи генерирует конфигурацию Angie динамически, либо подключают те или иные секции конфигурации из отдельных файлов и т.к. директивы acme_client
и acme
задаются на разных уровнях, то легко может возникнуть такая ситуация, когда в той или иной версии конфигурации не окажется ни одной директивы acme
ссылающейся на acme_client
. Ранее такие конфигурации считались невалидными, а теперь проверка корректности происходит более точечно и ошибка будет возникать только в случае, если директива acme
была указана в блоке server
, в котором нет ни одного валидного доменного имени в server_name
.
Кстати, познакомиться с возможностями автоматического выпуска TLS‑сертификатов проще всего прочитав руководство. В частности, из него можно узнать, что для выпуска wildcard‑сертификатов Angie может сам обрабатывать DNS‑запросы от ACME‑сервера — это существенно упрощает настройку.
Кэширование TLS-сертификатов при использовании переменных
И конечно же портировали всю функциональность из nginx 1.27.4, включая наиболее значимое нововведение: кэширование динамических TLS‑сертификатов, которые заданы переменными. Данная функциональность настраивается с помощью соответствующих директив: ssl_object_cache_inheritable
, ssl_certificate_cache
, proxy_ssl_certificate_cache
, grpc_ssl_certificate_cache
и uwsgi_ssl_certificate_cache
, и позволяет снизить нагрузку на CPU и задержку при использовании переменных в директивах ssl_certificate_cache
, proxy_ssl_certificate
и им подобных. Как раз очень актуально в комбинации с нашим ACME‑модулем, где сертификаты задаются через переменные:
ssl_certificate_cache max=10 inactive=6h valid=1d;
server {
listen 443 ssl;
server_name example.com www.example.com;
acme example;
ssl_certificate $acme_cert_example;
ssl_certificate_key $acme_cert_key_example;
}
Прочие полезные мелочи
Из незначительных улучшений: добавили отображение даты и времени компиляции, как в интерфейсе API статистики, так и в выводе командной строки по флагу ‑V
. Такая функциональность особенно полезна чтобы лучше различать отдельные сборки в наших репозиториях «ночных» сборок, которые с недавних пор стали доступны всем желающим: https://download.angie.software/angie‑nightly/ со всеми сторонними модулями. Но это пригодится и тем, кто собирает Angie самостоятельно из исходников.
Кроме того, исправили проблему с наследованием директив proxy_ssl_certificate
и proxy_ssl_certificate_key
, которая проявлялась при использовании в них переменных в сборках с NTLS (т. е. TLS‑библиотекой Tongsuo).
На этом пожалуй всё, что касается релиза 1.9.0.
Заключение и планы на ближайший релиз
Уже с 1.10.0 нас ждет много всего интересного. В частности, практически готова и находится сейчас на ревью возможность автоматического обновления списка проектируемых серверов в блоках upstream
по меткам Docker‑контейнеров. Благодаря ей Angie сможет автоматически подключаться к Docker API и мониторить события. Если вы стартуете контейнер с соответствующей меткой, то его IP‑адрес с заданным портом будет тут же добавлен в список серверов в блоке upstream
без перезагрузки конфигурации, а в случае остановки контейнера — удален. А контейнер, поставленный на паузу, переведет соответствующий сервер в состояние down
.
Сейчас список серверов в группах upstream
можно обновлять через DNS, в том числе из SRV‑записей, а PRO версии ещё дополнительно и через Rest API конфигурирования.
Также на подходе новый модуль кастомизации собираемых метрик статистики, который позволит пользователям самим в конфигурации заводить различные счетчики, вычисляемые из переменных или их комбинаций. Таким образом, появится возможность считать всё, на что хватит фантазии. К примеру, настроить метрику, которая бы вычисляла средний объем трафика, приходящийся на топ самых запрашиваемых URI. Почему бы и нет? Что сконфигурируете — то и будет рассчитываться, появится очень гибкая статистика. Её также можно будет запрашивать через наш API в формате JSON, либо отдавать непосредственно в Prometheus.
Кастомизация статистики, взаимодействие с Docker API и другие не менее интересные функциональные возможности появится уже в следующей версии, которые мы стараемся стабильно выпускать не реже чем раз в 3 месяца.
Кроме того надеюсь, что у меня хватит времени довести до релиза долгожданную возможность запуска приложений, которую я анонсировал в своем докладе на прошлой конференции HighLoad++.
Спасибо за внимание. Оставайтесь с нами!