# Angie 1.9: новые возможности и улучшения

*14.04.2025*

Подробный разбор новых возможностей Angie 1.9: сохранение зон разделяемой памяти с индексом кэша на диск,
персистентный переход на резервную группу серверов, 0-RTT в потоковом модуле и другие улучшения.

![Коллеги совещаются в фойе нашего офиса (в обработке ИИ в стиле Миядзаки)](https://habrastorage.org/r/w1560/getpro/habr/upload_files/a67/ebd/a00/a67ebda00801ad616e0590cb64b4fbe6.jpg)

Возможно, вы уже [читали в новостях](https://angie.software//news/releases/angie-1-9-0.md), что
накануне Дня космонавтики вышел новый стабильный выпуск Angie 1.9.0, форка
nginx, который продолжает развивать команда бывших разработчиков nginx. С
интервалом примерно в квартал мы стараемся выпускать новые стабильные версии и
радовать пользователей множеством улучшений. Данный релиз не стал исключением,
но одно дело читать сухой лог изменений, а совсем другое познакомиться с
функциональностью подробнее, узнать, как и в каких случаях её можно применить.

Список нововведений, на которых мы остановимся подробнее:

* Сохранение зон разделяемой памяти с индексом кэша на диск
* Персистентный переход на резервную группу проксируемых серверов
* 0-RTT в потоковом модуле
* Новый статус `busy` у проксируемых серверов во встроенном API статистики
* Улучшения ACME‑модуля, позволяющего автоматически получать TLS‑сертификаты
  Let's Encrypt и др.
* Кэширование TLS‑сертификатов при использовании переменных

За одним исключением, всё это вошло в состав свежей open source версии Angie и
доступно прямо сейчас [в наших репозиториях](https://angie.software//angie/docs/installation/external-modules/auth-jwt.md#installation).

А кроме того, коротко предвосхищу ожидания от будущей версии Angie 1.10, которая
должна появиться на свет где‑то уже в конце июня — начале июля.

## Сохранение зоны разделяемой памяти с индексом кэша на диск

Одним из самых интересных нововведений свежего релиза 1.9 является возможность
сохранить зону разделяемой памяти, которая хранит индекс кэша, на диск.

Для этого в директиве [proxy_cache_path](https://angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-cache-path)
помимо имени и размера зоны, теперь можно задать путь к файлу:

```nginx
proxy_cache_path  my_cache keys_zone=my_czone:256m:file=/path/to/my_cache.zone;
```

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

Что это дает? Ранее, для подгрузки кэша после перезапуска сервера, использовался
специальный процесс, т. н. загрузчик кэша (cache loader). Он обходил все файлы в
директории кэша и загружал метаинформацию в индекс, который хранится в
разделяемой памяти. Когда файлов очень много, то этот процесс может занимать
минуты, часы и даже сутки, при этом создавая дополнительную, порой ощутимую
нагрузку на жесткий диск. Кстати, в нашем мониторинге можно [наблюдать за этим
процессом](https://angie.software//angie/docs/configuration/modules/http/http_api.md#api-status-http-caches):
когда кэш ещё не перегружен, то значение поля `cold` будет `true`. Включать
такой сервер в работу возможно не во всех случаях, иногда это может увеличивать
задержки до неприемлемого уровня. В результате после перезапуска сервера
приходится ждать все это время, прежде чем вернуть сервер в строй.

Но если индекс, который хранит разделяемая память, сохранен на диске в виде
одного файла, то в отличие от минут, часов и порой даже суток, процесс загрузки
этого файла в память занимает считанные мгновения. Таким образом, подргузка кэша
с помощью процесса «cache loader» не требуется и на сервер можно пускать трафик
сразу после запуска Angie.

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

В будущих релизах мы планируем добавить сохранение зон разделяемой памяти и в
остальные модули.

## Персистентный переход на резервную группу проксируемых серверов (только PRO)

Другая интересная возможность, которая была добавлена, но на этот раз только в
версию PRO, касается HTTP‑балансировщика. Новая директива [backup_switch (PRO)](https://angie.software//angie/docs/configuration/modules/http/http_upstream.md#u-backup-switch)
теперь позволяет менять логику переключения на резервную группу серверов:

```nginx
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`‑группы. Таким образом, как
только один из серверов в основной группе станет доступны, то на него сразу же
будет направлен весь последующий трафик. В ряде конфигураций такое поведение не
является приемлемым и в случае переключения на резервную группу требуется
продолжать балансировать запросы на неё. Именно такой режим включает директива:

```nginx
backup_switch permanent;
```

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

Если в опции `permanent` задан таймаут, например, `permanent=5m`, то попытки
выбрать сервер в основной группе будут происходить, но не чаще, чем раз в
заданный интервал. В случае успеха такой попытки — произойдет переключение
обратно на основную группу. Такой режим является компромиссными и убережет от
слишком частых переключений между резервной и основной группой в случае, если
такое переключение все же требуется, но сервера в основной группе сохраняют
нестабильность или остаются быть перегруженными.

Кроме этого в API статистики появился новый объект `backup_switch`, который
содержит числовое поле `active`. Этот объект доступен только когда включен
режим `backup_switch permanent`. Поле `active` отображает текущую активную
группу: 0, если активная основная группа и 1 в случае `backup`. В расширенной
версии балансировщика [Angie ADC](https://angie.software//adc/index.md) резервных групп можно
задать больше 1, поэтому и значение поля `active` в этом случае может быть >1.

Если опция задана с интервалом времени (например, `permanent=1m`), то при
переключении на резервную группу в объекте `backup_switch` также появляется
поле `timeout`, которое содержит число миллисекунд до очередной попытки
переключиться на основную группу.

В будущих версиях планируем реализовать возможность настройки ещё более сложной
логики переключения между резервными группами (например по количеству доступных
серверов в группе, нагрузке на них и т. д.), а также новый интерфейс в API,
который позволит принудительно переключать группы по команде извне.

Далее о более простых, но полезных функциях, которые были реализованы, как в
open source версии, так и в PRO.

## 0-RTT в потоковом модуле

В потоковый модуль `stream` добавили возможность использовать механизм TLS 1.3
Early Data (0-RTT), который ранее был доступен только в HTTP-модуле. Включается
такой же [директивой](https://angie.software//angie/docs/configuration/modules/stream/stream_ssl.md#s-ssl-early-data):

```nginx
ssl_early_data on;
```

Данный механизм позволяет клиенту отправить данные до завершения стадии
согласования соединения TLSv1.3, что сокращает задержку от момента подключения
до момента обработки данных при терминации TLS. Но следует иметь в виду, что
этот механизм уязвим к т.н. [атакам повторного воспроизведения](https://datatracker.ietf.org/doc/html/rfc8470) (replay), поэтому включать его
можно только в случае, если сам веб-сервис или протокол, который проксируется
через потоковый модуль, защищены от атак подобного рода.

## Новый статус "busy" у проксируемых серверов

Следующее нововведение — это новый статус `busy`, который может отображаться в
[поле state](https://angie.software//angie/docs/configuration/modules/http/http_upstream.md#http-upstream)
у проксируемых серверов в нашем API статистики. Данный статус можно увидеть
только в том случае, если в конфигурации сервера в upstream‑группе настроено
ограничение [max_conns](https://angie.software//angie/docs/configuration/modules/http/http_upstream.md#u-server):

```nginx
server backend.example.com:80 max_conns=128;
```

Как не трудно догадаться, если сервер уперся в ограничение по соединениям, то
`state` у него сменится на `busy` до того момента, пока число соединений не
опустится ниже лимита (либо он выключится и перейдет в один из других режимов
`down`/`unhealthy`/`unavailable`). Ранее, вместо `busy`, сервер
оставался в статусе `up`, пока был живым, однако запросы на него направляться
не могли из‑за ограничения `max_conns`. Поэтому для лучшей индикации этого
состояния и причин, по которым новые запросы не направляются на сервер — был
добавлен дополнительный статус.

## Доработки ACME-модуля

Следующая группа улучшений связана с дальнейшим развитием функциональности по
[автоматическому выпуску сертификатов ACME](https://angie.software//angie/docs/configuration/modules/http/http_acme.md#http-acme). Служат они
для улучшения пользовательского опыта с данным модулем и были разработаны на
основе обратной связи от нашего [сообщества в Telegram](https://t.me/angie_support).

В [acme_client](https://angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-client) добавлен новый параметр `renew_on_load`, который
позволяет гораздо проще принудительно запустить процесс перевыпуска сертификатов
при загрузке конфигурации, если вдруг это зачем‑то потребовалось (например,
стало известно об утечке ключей).

Также поменялся режим работы опции `enabled=off`. Он стал более удобным в
использовании и теперь позволяет временно отключить перевыпуск сертификатов, но
если ранее они были уже выпущены, то доступ к ним сохраняется и их можно
продолжать использовать в конфигурации.

В новой версии также был пересмотрен подход к валидации конфигурации ACME
директив. Ранее директивы `acme_client` требовали обязательного наличия
минимум одной директивы [acme](https://angie.software//angie/docs/configuration/modules/http/http_acme.md#id4) в блоках `server`, что было не
всегда удобно. Часто пользователи генерирует конфигурацию Angie динамически,
либо подключают те или иные секции конфигурации из отдельных файлов и т.к.
директивы `acme_client` и `acme` задаются на разных уровнях, то легко может
возникнуть такая ситуация, когда в той или иной версии конфигурации не окажется
ни одной директивы `acme` ссылающейся на `acme_client`. Ранее такие
конфигурации считались невалидными, а теперь проверка корректности происходит
более точечно и ошибка будет возникать только в случае, если директива `acme`
была указана в блоке `server`, в котором нет ни одного валидного доменного
имени в `server_name`.

Кстати, познакомиться с возможностями автоматического выпуска TLS‑сертификатов
проще всего прочитав [руководство](https://angie.software//angie/docs/configuration/acme.md#acme-config). В частности, из него можно
узнать, что для выпуска wildcard‑сертификатов Angie может сам обрабатывать
DNS‑запросы от ACME‑сервера — это существенно упрощает настройку.

## Кэширование TLS-сертификатов при использовании переменных

И конечно же портировали всю функциональность из nginx 1.27.4, включая наиболее
значимое нововведение: кэширование динамических TLS‑сертификатов, которые заданы
переменными. Данная функциональность настраивается с помощью соответствующих
директив: [ssl_object_cache_inheritable](https://angie.software//angie/docs/configuration/modules/core.md#ssl-object-cache-inheritable),
[ssl_certificate_cache](https://angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-certificate-cache),
[proxy_ssl_certificate_cache](https://angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-ssl-certificate-cache),
[grpc_ssl_certificate_cache](https://angie.software//angie/docs/configuration/modules/http/http_grpc.md#grpc-ssl-certificate-cache),
[uwsgi_ssl_certificate_cache](https://angie.software//angie/docs/configuration/modules/http/http_uwsgi.md#uwsgi-ssl-certificate-cache),
и позволяет снизить нагрузку на CPU и задержку при использовании переменных в
директивах `ssl_certificate_cache`, `proxy_ssl_certificate` и им подобных.
Как раз очень актуально в комбинации с нашим ACME‑модулем, где сертификаты
задаются через переменные:

```nginx
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/](https://download.angie.software/angie-nightly/) со всеми
[сторонними модулями](https://angie.software//angie/docs/installation/external-modules/index.md#install-thirdpartymodules). Но это пригодится и тем, кто
собирает Angie самостоятельно [из исходников](https://angie.software//angie/docs/installation/sourcebuild.md#sourcebuild).

Кроме того, исправили проблему с наследованием директив [proxy_ssl_certificate](https://angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-ssl-certificate)
и [proxy_ssl_certificate_key](https://angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-ssl-certificate-key),
которая проявлялась при использовании в них переменных в сборках с [NTLS](https://angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-ntls)
(т. е. TLS‑библиотекой [Tongsuo](https://tongsuo.net/en/docs/eco)).

На этом пожалуй всё, что касается релиза 1.9.0.

## Заключение и планы на ближайший релиз

Уже с 1.10.0 нас ждет много всего интересного. В частности, практически готова и
находится сейчас на ревью возможность автоматического обновления списка
проектируемых серверов в блоках `upstream` по меткам Docker‑контейнеров.
Благодаря ей Angie сможет автоматически подключаться к Docker API и мониторить
события. Если вы стартуете контейнер с соответствующей меткой, то его IP‑адрес с
заданным портом будет тут же добавлен в список серверов в блоке `upstream` без
перезагрузки конфигурации, а в случае остановки контейнера — удален. А
контейнер, поставленный на паузу, переведет соответствующий сервер в состояние
`down`.

Сейчас список серверов в группах `upstream` можно обновлять [через DNS](https://angie.software//angie/docs/configuration/modules/http/http_upstream.md#reresolve), в том числе из SRV‑записей, а PRO версии ещё дополнительно
и [через REST API](https://angie.software//angie/docs/configuration/modules/http/http_api.md#http-api) конфигурирования.

Также на подходе новый модуль кастомизации собираемых метрик статистики, который
позволит пользователям самим в конфигурации заводить различные счетчики,
вычисляемые из переменных или их комбинаций. Таким образом, появится возможность
считать всё, на что хватит фантазии. К примеру, настроить метрику, которая бы
вычисляла средний объем трафика, приходящийся на топ самых запрашиваемых URI.
Почему бы и нет? Что сконфигурируете — то и будет рассчитываться, появится очень
гибкая статистика. Её также можно будет запрашивать через [наш API в
формате JSON](https://angie.software//angie/docs/configuration/modules/http/http_api.md#http-api), либо отдавать [непосредственно в Prometheus](https://angie.software//angie/docs/configuration/modules/http/http_prometheus.md#http-prometheus).

Кастомизация статистики, взаимодействие с Docker API и другие не менее
интересные функциональные возможности появится уже в следующей версии, которые
мы стараемся стабильно выпускать не реже чем раз в 3 месяца.

Кроме того надеюсь, что у меня хватит времени довести до релиза долгожданную
возможность запуска приложений, которую я анонсировал в [своем докладе на
прошлой конференции HighLoad++](https://highload.ru/moscow/2024/abstracts/13181).

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