Динамический модуль Nginx - это разделяемая библиотека (.so), которую веб-сервер загружает во время запуска или перезагрузки конфигурации. Вы получаете возможность добавлять функциональность - авторизацию, сжатие, балансировку, защиту - без полной перекомпиляции основного бинарного файла. Директива load_module подключает готовый модуль, а флаг --add-dynamic-module при сборке из исходников создаёт такой модуль.
Этот подход решает главную проблему: раньше для подключения стороннего расширения требовалось пересобрать Nginx целиком. Теперь достаточно заменить один .so-файл и перезагрузить конфигурацию. Материал построен на практических сценариях - вы пройдёте путь от подготовки окружения до диагностики ошибок совместимости.
Что такое динамические модули Nginx и зачем они нужны
Nginx с момента версии 1.9.11 поддерживает динамическую загрузку модулей. До этого все расширения вкомпилировались статически на этапе сборки. Статическая компоновка даёт минимальный выигрыш в производительности за счёт отсутствия накладных расходов на загрузку разделяемых библиотек, но жёстко привязывает функциональность к конкретному бинарному файлу.
Динамический модуль - это файл с расширением .so, который Nginx загружает в память при старте. Вы можете подключить модуль, предоставленный разработчиком дистрибутива, или собрать собственный из исходников. После добавления директивы load_module в конфигурацию и перезагрузки сервера новая функциональность активируется. Для отключения достаточно закомментировать строку и перезагрузить Nginx.
Типовые задачи, решаемые динамическими модулями:
- Делегированная аутентификация через
ngx_http_auth_request_module - Отдача предварительно сжатых файлов через
ngx_http_gzip_static_module - Балансировка нагрузки с альтернативными алгоритмами, например
ngx_http_upstream_fair_module - Защита от DDoS-атак и фильтрация трафика
- Интеграция с языками программирования через модули вроде
ngx_http_lua_module
Практическая ценность динамических модулей раскрывается в трёх сценариях. Первый - использование предсобранных пакетов из официальных репозиториев, когда модуль устанавливается отдельно от ядра Nginx. Второй - самостоятельная сборка специфичного расширения, отсутствующего в стандартной поставке. Третий - распространение собственных наработок внутри команды без передачи полного бинарного файла. Если вы только начинаете разбираться с архитектурой веб-сервера, рекомендуем предварительно изучить Nginx как маршрутизатор уровня приложений - там разобраны базовые принципы конфигурации.
Сборка динамического модуля из исходников
Самостоятельная компиляция требуется, когда нужный модуль отсутствует в пакетном менеджере вашего дистрибутива или когда необходима специфичная версия. Процесс состоит из трёх этапов: подготовка окружения, конфигурирование с флагом --add-dynamic-module и компиляция.
Подготовка сборочного окружения
Для компиляции модулей Nginx необходимы те же зависимости, что и для сборки самого веб-сервера. Установите пакеты:
# Debian/Ubuntu
apt-get install build-essential libpcre3-dev zlib1g-dev libssl-dev
# CentOS/RHEL
yum groupinstall "Development Tools"
yum install pcre-devel zlib-devel openssl-devel
Загрузите исходники Nginx той же версии, которая работает на вашем сервере. Проверьте текущую версию командой nginx -v. Скачайте соответствующий архив с официального сайта:
wget http://nginx.org/download/nginx-1.26.0.tar.gz
tar -xzf nginx-1.26.0.tar.gz
Исходники модуля получите из репозитория разработчика. Для примера возьмём ngx_http_auth_request_module - он уже включён в стандартную поставку Nginx как опциональный, но демонстрирует общий принцип. Сторонние модули клонируются через git:
git clone https://github.com/gnosek/nginx-upstream-fair.git
Критически важно: версия исходников Nginx должна совпадать с версией установленного экземпляра. Несовпадение приведёт к ошибке «module is not binary compatible» при загрузке.
Конфигурирование и компиляция с --add-dynamic-module
Перейдите в директорию с исходниками Nginx и запустите ./configure с флагом --add-dynamic-module. Флаг принимает путь к директории с исходным кодом модуля:
cd nginx-1.26.0
./configure --add-dynamic-module=../nginx-upstream-fair
Вы можете указать несколько модулей одновременно, перечислив флаги последовательно:
./configure \
--add-dynamic-module=../module-one \
--add-dynamic-module=../module-two
После конфигурирования запустите компиляцию только модулей. Команда make modules собирает исключительно динамические расширения, не затрагивая основной бинарный файл. Это быстрее и безопаснее, чем полная сборка:
make modules
Собранные .so-файлы находятся в поддиректории objs/. Скопируйте их в каталог модулей Nginx:
cp objs/*.so /etc/nginx/modules/
Путь /etc/nginx/modules/ - общепринятый, но вы можете выбрать любое расположение. Главное - указать корректный путь в директиве load_module.
Подключение динамического модуля в работающий Nginx
Активация модуля выполняется добавлением одной строки в конфигурацию и последующей перезагрузкой сервера. Процедура безопасна: Nginx проверяет синтаксис и совместимость модуля до применения изменений.
Синтаксис директивы load_module
Директива load_module размещается на верхнем уровне конфигурационного файла nginx.conf, до блока events. Она принимает абсолютный или относительный путь к .so-файлу:
load_module /etc/nginx/modules/ngx_http_auth_request_module.so;
events {
worker_connections 1024;
}
http {
# основная конфигурация
}
Относительный путь отсчитывается от префикса сборки Nginx, обычно /etc/nginx/ или /usr/local/nginx/. Рекомендуем использовать абсолютные пути - это исключает неоднозначность.
Порядок загрузки модулей соответствует порядку директив в конфигурации. Если модуль B зависит от модуля A, директива для A должна располагаться выше. Дважды загрузить один модуль нельзя - Nginx выдаст ошибку при старте. Выгрузить модуль без перезапуска невозможно, поэтому для отключения требуется закомментировать директиву и перезагрузить сервер.
Проверка и активация модуля
Перед применением изменений проверьте синтаксис конфигурации:
nginx -t
Вывод syntax is ok и test is successful подтверждает корректность. При наличии ошибок вы получите точное указание на проблемную строку.
Для плавной перезагрузки без разрыва активных соединений используйте:
nginx -s reload
Убедиться, что модуль загружен, можно несколькими способами. Команда nginx -V 2>&1 показывает полную строку конфигурации сборки, включая статические модули. Для просмотра динамических модулей проверьте вывод на наличие load_module в работающей конфигурации или используйте специализированные страницы статуса. Детальный разбор методов диагностики мы приводили в статье о ключевых метриках мониторинга Nginx - там описаны инструменты для отслеживания состояния сервера.
Управление динамическими модулями: добавление, отключение, обновление
Жизненный цикл модуля включает три операции: первичное добавление, временное отключение и обновление до новой версии. Каждая операция выполняется без остановки сервера.
Добавление нового модуля: скопируйте .so-файл в директорию /etc/nginx/modules/, пропишите load_module в конфигурации, выполните nginx -t && nginx -s reload. Модуль активирован.
Отключение: закомментируйте строку load_module, проверьте конфигурацию и перезагрузите сервер. Функциональность модуля перестаёт работать, сам .so-файл остаётся на диске - его можно удалить позже.
Обновление модуля: замените .so-файл новым, сохранив прежнее имя и путь. Проверьте конфигурацию и выполните перезагрузку. Если модуль обрабатывает критичные запросы, рассмотрите staggered reload на кластере из нескольких экземпляров Nginx.
Обеспечение совместимости версий
Модуль должен быть собран для той же версии Nginx, в которую он загружается. Проверьте версию сервера:
nginx -v
# nginx version: nginx/1.26.0
При несовпадении версий вы получите ошибку:
nginx: [emerg] module "/etc/nginx/modules/ngx_http_example_module.so" is not binary compatible
Решение - пересборка модуля из исходников той же версии, что и установленный Nginx. Если вы обновили веб-сервер через пакетный менеджер, пересоберите все динамические модули заново.
Обновление модуля без простоя
Процедура безопасного обновления:
- Соберите новую версию модуля
- Скопируйте .so-файл во временное расположение
- Подмените старый файл новым атомарной операцией
mv - Выполните
nginx -t - Выполните
nginx -s reload
Для кластерных конфигураций с балансировщиком нагрузки применяйте последовательную перезагрузку узлов. Выведите один сервер из балансировки, обновите модуль, перезагрузите, верните в кластер. Повторите для остальных узлов. Этот подход исключает деградацию сервиса при обновлении.
Практические примеры: авторизация, сжатие, балансировка
Разберём три рабочих кейса, которые покрывают наиболее частые запросы администраторов. Каждый пример содержит минимальную конфигурацию, готовую к адаптации под вашу среду.
Настройка делегированной аутентификации
Модуль ngx_http_auth_request_module перенаправляет проверку прав доступа на внутренний endpoint. Это позволяет реализовать централизованную аутентификацию без дублирования логики в каждом приложении.
Сборка модуля (включён в стандартные исходники Nginx как опциональный):
./configure --add-dynamic-module=src/http/modules/auth_request
make modules
cp objs/ngx_http_auth_request_module.so /etc/nginx/modules/
Конфигурация:
load_module /etc/nginx/modules/ngx_http_auth_request_module.so;
http {
server {
location /private/ {
auth_request /auth;
auth_request_set $auth_user $upstream_http_x_user;
proxy_pass http://backend;
}
location = /auth {
internal;
proxy_pass http://auth-service/verify;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
}
}
При запросе к /private/ Nginx отправляет подзапрос на /auth. Если сервис аутентификации возвращает 2xx, основной запрос проксируется на бэкенд. Код 401 или 403 от /auth немедленно возвращается клиенту.
Эффективное сжатие статических файлов
Модуль ngx_http_gzip_static_module отдаёт предварительно сжатые .gz-версии файлов, экономя процессорное время на динамическом сжатии. Подходит для статики, которая редко меняется: CSS, JavaScript, шрифты.
Сборка:
./configure --add-dynamic-module=src/http/modules/gzip_static
make modules
cp objs/ngx_http_gzip_static_module.so /etc/nginx/modules/
Конфигурация:
load_module /etc/nginx/modules/ngx_http_gzip_static_module.so;
http {
server {
location /static/ {
gzip_static on;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
}
Предварительно сожмите файлы утилитой gzip:
gzip -k -9 /var/www/static/style.css
# создаст /var/www/static/style.css.gz
Nginx отдаст .gz-файл клиентам, поддерживающим сжатие, без дополнительной нагрузки на CPU. Для клиентов без поддержки gzip отдаётся оригинальный файл.
Улучшенная балансировка нагрузки
Сторонний модуль ngx_http_upstream_fair_module реализует алгоритм балансировки, который распределяет запросы пропорционально загрузке бэкендов. В отличие от round-robin, он не отправляет новый запрос на занятый сервер.
Сборка:
git clone https://github.com/gnosek/nginx-upstream-fair.git
cd nginx-1.26.0
./configure --add-dynamic-module=../nginx-upstream-fair
make modules
cp objs/ngx_http_upstream_fair_module.so /etc/nginx/modules/
Конфигурация:
load_module /etc/nginx/modules/ngx_http_upstream_fair_module.so;
http {
upstream backend_cluster {
fair;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
keepalive 32;
}
server {
location / {
proxy_pass http://backend_cluster;
}
}
}
Алгоритм fair полезен в сценариях с неоднородными запросами: когда одни запросы выполняются быстро, а другие требуют длительной обработки. Round-robin в таких условиях может перегрузить один из серверов, fair - нет. Для углублённого изучения балансировки ознакомьтесь с материалом Nginx как балансировщик нагрузки - там разобраны health checks и отказоустойчивость.
Диагностика и устранение ошибок при загрузке модулей
Проблемы при подключении модулей делятся на три категории: ошибки файловой системы, несовместимость версий и синтаксические ошибки в директивах модуля. Разберём каждую с методами диагностики.
Ошибка «cannot open shared object file»
Полный текст ошибки:
nginx: [emerg] cannot open shared object file "/etc/nginx/modules/ngx_http_example_module.so": No such file or directory
Причины и решения:
- Файл отсутствует по указанному пути - проверьте командой
ls -la /etc/nginx/modules/ - Опечатка в пути - скопируйте путь из ошибки и сверьте с реальным расположением
- Недостаточно прав - установите
chmod 644на .so-файл иchown root:root - SELinux блокирует доступ - проверьте контекст безопасности:
ls -Z /etc/nginx/modules/
Инструмент strace показывает системные вызовы и точно указывает, на каком этапе происходит сбой:
strace -e openat nginx -t 2>&1 | grep module_name
Ошибка «module is not binary compatible»
Эта ошибка означает, что модуль собран для другой версии Nginx. Сравните версии:
nginx -v
strings /etc/nginx/modules/ngx_http_example_module.so | grep "nginx version"
Решение - пересборка модуля из исходников той же версии, что и установленный Nginx. Если сервер обновлялся через пакетный менеджер, загрузите исходники соответствующей версии с официального сайта и повторите компиляцию.
Проверить зависимости модуля можно утилитой ldd:
ldd /etc/nginx/modules/ngx_http_example_module.so
Отсутствующие библиотеки помечаются как «not found». Установите недостающие пакеты и повторите загрузку модуля.
Рекомендация: все изменения с динамическими модулями сначала тестируйте в staging-среде, идентичной production по версиям ОС и Nginx. Это предотвратит падение боевого сервера из-за несовместимости.
Статические vs динамические модули: что выбрать
Выбор между статической и динамической загрузкой модуля определяется тремя факторами: производительностью, удобством сопровождения и политикой безопасности.
Статическая компиляция встраивает код модуля непосредственно в бинарный файл Nginx. Вызовы функций происходят напрямую, без накладных расходов на динамическое связывание. Разница в производительности составляет доли процента и заметна только на предельных нагрузках - от 50 000 одновременных соединений и выше. Статические модули нельзя отключить без перекомпиляции, что усложняет аудит безопасности и обновление.
Динамические модули загружаются во время выполнения. Накладные расходы - однократная операция связывания при старте, которая занимает миллисекунды. Вы получаете возможность добавлять и удалять функциональность правкой конфигурации, распространять модули отдельно от ядра и использовать сторонние расширения без модификации системных пакетов.
Рекомендации по выбору:
- Стандартные модули из официальной поставки (http, stream, mail) - статическая компиляция, если вы собираете Nginx самостоятельно
- Сторонние модули с активной разработкой - динамическая загрузка для упрощения обновлений
- Редко используемые модули - динамическая загрузка, чтобы не увеличивать размер бинарного файла
- Высоконагруженные системы с жёсткими требованиями к latency - статическая компиляция критичных модулей
Практическое правило: начинайте с динамических модулей. Если бенчмарки покажут, что накладные расходы на загрузку значимы для вашего сценария, переходите на статическую компоновку. Для 95% инсталляций разница незаметна. Дополнительные приёмы оптимизации конфигурации описаны в руководстве по настройке Nginx для высоконагруженных приложений.