upstream-jdomain: Асинхронный модуль разрешения доменных имен для NGINX upstream
Установка
Вы можете установить этот модуль в любой дистрибутив на базе RHEL, включая, но не ограничиваясь:
- RedHat Enterprise Linux 7, 8, 9 и 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-upstream-jdomain
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-upstream-jdomain
Включите модуль, добавив следующее в верхнюю часть файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_upstream_jdomain_module.so;
Этот документ описывает nginx-module-upstream-jdomain v1.5.2, выпущенный 9 декабря 2024 года.
Асинхронный модуль разрешения доменных имен для nginx upstream.
Этот модуль позволяет использовать доменное имя в блоке upstream и ожидать, что доменное имя будет динамически разрешено, чтобы ваш upstream мог быть устойчивым к обновлениям DNS-записей.
Модуль не выполняет разрешение DNS автоматически через определенные интервалы времени. Вместо этого разрешение DNS должно быть инициировано запросом к данному upstream. Если nginx обслуживает соединение, предназначенное для jdomain upstream, и истек заданный interval, то модуль выполнит DNS-запрос.
Модуль совместим с другими директивами области upstream. Это означает, что вы можете заполнять блок upstream несколькими директивами jdomain, несколькими директивами server, keepalive, директивами балансировки нагрузки и т.д. Обратите внимание, что если в блоке upstream не указано иное средство балансировки нагрузки, этот модуль использует алгоритм балансировки нагрузки по умолчанию, встроенный в ядро nginx, который основан на круговом распределении.
Важно: Если будет указана альтернативная алгоритм балансировки нагрузки, он должен находиться перед директивой jdomain в блоке upstream! Если это не будет соблюдено, nginx упадет во время выполнения! Это связано с тем, что многие другие модули балансировки нагрузки явно расширяют встроенный круговой алгоритм, и, таким образом, могут перезаписывать обработчики инициализации jdomain, поскольку jdomain технически также является модулем балансировки нагрузки. Хотя это может не относиться ко всем модулям балансировки нагрузки, лучше перестраховаться и разместить jdomain после.
Важно: Из-за неблокирующей природы этого модуля и того факта, что его разрешение DNS инициируется входящими запросами, запрос, который инициирует поиск, фактически все равно будет перенаправлен на upstream, который был разрешен и кэширован до того, как произойдет DNS-запрос. В зависимости от сценария это может привести к единичному сбою при изменении состояний upstream. Это важно учитывать, чтобы обеспечить плавные переходы ваших upstream.
Этот репозиторий является форком репозитория, первоначально созданного wdaike. Поскольку тот проект больше не поддерживается, этот репозиторий стремится стать его преемником и теперь имеет несколько новых функций.
Использование
resolver 8.8.8.8; # Ваш локальный DNS-сервер
## Базовый upstream с использованием доменного имени по умолчанию на порт 80.
upstream backend_01 {
jdomain example.com;
}
## Базовый upstream с указанием другого порта.
upstream backend_02 {
jdomain example.com port=8080;
}
## Upstream с резервным сервером на случай, если хост не найден или есть ошибки формата
## при разрешении DNS.
upstream backend_03 {
server 127.0.0.2 backup;
jdomain example.com;
}
## Upstream, который будет использовать резервный сервер для любых и всех ошибок разрешения DNS.
upstream backend_04 {
server 127.0.0.2 backup;
jdomain example.com strict;
}
server {
listen 127.0.0.2:80;
return 502 'Ошибка.';
}
Синтаксис
Синтаксис: jdomain <domain-name> [port=80] [max_ips=4] [interval=1] [strict]
Контекст: upstream
Атрибуты:
port: Порт, на котором слушает бэкенд. (По умолчанию: 80)
max_ips: Размер буфера IP. Максимальное количество разрешенных IP для кэширования. (По умолчанию: 4)
interval: Сколько секунд для разрешения доменного имени. (По умолчанию: 1)
ipver: Используются только адреса семейства IPv4 или IPv6, если определено (По умолчанию: 0)
strict: Требует, чтобы разрешение DNS прошло успешно и вернуло адреса,
в противном случае помечает основной сервер и пиры как недоступные и
принуждает использовать другие серверы в блоке upstream, если они
присутствуют. Неудачное разрешение может быть вызвано таймаутом, сбоем DNS
сервера, отказом в соединении, ответом без
адресов и т.д.
Смотрите https://www.nginx.com/resources/wiki/modules/domain_resolve/ для получения подробной информации.
Разработка
Предварительные требования
Чтобы облегчить локальную разработку и позволить вам собирать и тестировать модуль, вам понадобятся некоторые инструменты.
- Docker: для предоставления среды для легкого воспроизведения идеальных условий для сборки и тестирования.
- act: для симуляции выполнения рабочих процессов github actions локально, чтобы избежать необходимости отправлять коммиты только для того, чтобы посмотреть, как CI не проходит.
- rust: зависимость от
cargo-make. - cargo-make: для выполнения общих задач разработки, таких как сборка, тестирование и форматирование кода.
Запуск задач
cargo-make — это продвинутый инструмент для выполнения задач, который позволит вам легко выполнять
общие операции разработки, такие как форматирование кода, сборка модуля,
запуск тестового набора и анализ кода. Вы можете увидеть определения задач в файле Makefile.toml. Установка cargo-make приведет к созданию отдельного исполняемого файла под названием makers, а также расширения cargo, которое можно выполнить через cargo make. Поскольку этот проект не является rust пакетом, рекомендуется просто использовать makers.
Также обратите внимание, что для простоты инструмент для выполнения задач использует docker для выполнения всех задач. Это означает, что собранный бинарный файл не нацелен на вашу хост-платформу.
Задача по умолчанию
Чтобы добавить ценность, задача по умолчанию (т.е. просто запуск makers в одиночку) начнет
интерактивную сессию bash внутри контейнера docker, используемого для этого проекта.
Это должно помочь с отладкой и общим рабочим процессом.
Форматирование
Неправильно отформатированный код приведет к сбою задания линтинга в github actions. Чтобы избежать этого, вы можете запустить задачу форматирования перед отправкой новых изменений, следующим образом:
makers format
Это форматирование выполняется с помощью инструмента под названием clang-format. Вы можете найти параметры конфигурации для этого в файле ./.clang-format.
Статический анализ кода
Вы можете запустить статический анализ кода с помощью задачи анализа:
makers analyse
Этот анализ выполняется с помощью инструмента под названием clang-tidy. Вы можете найти параметры конфигурации для этого в файле ./.clang-tidy.
Тестирование
Вы можете запустить тестовый набор, используя задачу тестирования, следующим образом:
makers test
Отладка
Мы можем использовать valgrind и gdb на nginx изнутри контейнера.
Сначала откройте интерактивную оболочку в контейнере с помощью:
$ makers
Мы будем использовать эту сессию для запуска valgrind:
$ valgrind --vgdb=full --vgdb-error=0 /github/workspace/bin/static/nginx -p/github/workspace/t/servroot -cconf/nginx.conf
==15== Memcheck, детектор ошибок памяти
==15== Copyright (C) 2002-2017, и GNU GPL, авторы Julian Seward и др.
==15== Используя Valgrind-3.13.0 и LibVEX; повторный запуск с -h для информации об авторских правах
==15== Команда: /github/workspace/bin/static/nginx -p/github/workspace/t/servroot -cconf/nginx.conf
==15==
==15== (действие при запуске) vgdb me ...
==15==
==15== ДЛЯ ОТЛАДКИ ЭТОГО ПРОЦЕССА С ПОМОЩЬЮ GDB: запустите GDB так
==15== /path/to/gdb /github/workspace/bin/static/nginx
==15== и затем дайте GDB следующую команду
==15== target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=15
==15== --pid не обязателен, если запущен только один процесс valgrind
==15==
Затем найдите идентификатор контейнера, чтобы мы могли открыть еще одну сессию внутри него:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55fab1e069ba act-github-actions-nginx-module-toolbox "bash" 4 seconds ago Up 3 seconds 0.0.0.0:1984->1984/tcp serene_newton
Используйте либо имя, либо ID, чтобы выполнить bash-сессию внутри контейнера:
$ docker exec -it serene_newton bash
Мы будем использовать эту сессию для запуска gdb и нацеливания на сервер gdb valgrind, который мы запустили в другой сессии:
$ gdb /github/workspace/bin/static/nginx
GNU gdb (GDB) Red Hat Enterprise Linux 8.0.1-30.amzn2.0.3
Copyright (C) 2017 Free Software Foundation, Inc.
Лицензия GPLv3+: GNU GPL версия 3 или более поздняя <http://gnu.org/licenses/gpl.html>
Это бесплатное программное обеспечение: вы можете изменять и распространять его.
Гарантии НЕТ, в той мере, в какой это разрешено законом. Введите "show copying"
и "show warranty" для получения подробной информации.
Этот GDB был сконфигурирован как "x86_64-redhat-linux-gnu".
Введите "show configuration" для получения подробностей конфигурации.
Для инструкций по отчетам об ошибках, пожалуйста, смотрите:
<http://www.gnu.org/software/gdb/bugs/>.
Найдите руководство GDB и другие ресурсы документации онлайн по адресу:
<http://www.gnu.org/software/gdb/documentation/>.
Для получения помощи введите "help".
Введите "apropos word", чтобы искать команды, связанные с "word"...
Чтение символов из /github/workspace/bin/static/nginx...готово.
(gdb)
С командной строки gdb нацелитесь на процесс valgrind и начните отладку:
(gdb) target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=15
Удаленная отладка с использованием | /usr/lib64/valgrind/../../bin/vgdb --pid=15
пересылка данных между gdb и процессом 15
предупреждение: удаленная цель не поддерживает передачу файлов, попытка получить доступ к файлам из локальной файловой системы.
Чтение символов из /lib64/ld-linux-x86-64.so.2...(символы отладки не найдены)...готово.
0x0000000004000ef0 in _start () from /lib64/ld-linux-x86-64.so.2
Отсутствуют отдельные отладочные информации, используйте: debuginfo-install glibc-2.26-35.amzn2.x86_64
(gdb)
Запуск GitHub Actions
С помощью act вы можете смоделировать рабочий процесс, который будет выполняться на серверах GitHub после того, как вы внесете изменения.
В основном рабочем процессе есть более одной задачи, поэтому вам нужно указать задачу тестирования, когда вы запускаете act. Например, вы можете использовать эту команду для проверки форматирования кода:
act -vj lint
Обратите внимание, что задача lint не форматирует ваш код, она только проверяет, что форматирование соответствует ожиданиям.
Также обратите внимание, что -v используется для включения подробного режима, чтобы дать больше информации о том, что делает act.
Задачи, которые вы можете (и должны) запускать локально, это lint, build, analyse и test. Задача test зависит от вывода задачи build. Чтобы сохранить вывод задачи сборки, вы можете добавить флаг -b к act, или вы можете просто использовать инструмент для выполнения задач для сборки.
Известные проблемы
На данный момент? Нет! 🎉
Если вы обнаружите ошибку или у вас есть вопрос, пожалуйста, откройте проблему.
Оригинальный автор
wdaike wdaike@163.com (https://github.com/wdaike), Baidu Inc.
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-upstream-jdomain.