Pull to refresh

Что нового в Angie 1.9 и что ожидать от 1.10?

Level of difficultyEasy
Reading time9 min
Views2.6K
Коллеги совещаются в фойе нашего офиса (в обработке ИИ в стиле Миядзаки)
Коллеги совещаются в фойе нашего офиса (в обработке ИИ в стиле Миядзаки)

Возможно, вы уже читали в новостях, что накануне Дня космонавтики вышел новый стабильный выпуск 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++.

Спасибо за внимание. Оставайтесь с нами!

Tags:
Hubs:
+39
Comments10

Articles