Содержание
Введение
Доброго времени суток. Сегодня хочу рассказать про работу с Nginx Unit простыми словами. Поговорим о том что такое NGINX UNIT, как с ним работать, какие проблемы могут возникнуть. Не буду затягивать, так что давайте приступим к обзору :)
Что такое Nginx Unit?
NGINX Unit — это новый веб-сервер, выпущенный в 2017 году разработчиками оригинального NGINX, для запуска веб-приложений. Веб-сервер имеет открытый исходный код, который доступен на Github.
NGINX UNIT динамический и не требует перезагрузки веб-сервера для применения конфигурационных файлов благодаря использованию REST API для взаимодействия с ним.
На NGINX UNIT можно настроить сервер для использования статических файлов (к примеру запустить одностраничный сайт или собранное React приложение) или же использовать один из встроенных модулей для запуска приложений на Python, PHP, NodeJS, Java и других языках. Полный список можно увидеть на официальном сайте.
Те, кто хочет попробовать веб-сервер могут следовать статье и таким образом изучать работу с ним.
Установка
Для примера будет установлен Nginx Unit последней версии с официального репозитория на виртуальной машине на Ubuntu 22.04. Если вы используете другую ОС, руководство по ней можно найти тут.
Загрузка и сохранение ключей Nginx Unit
sudo curl --output /usr/share/keyrings/nginx-keyring.gpg https://unit.nginx.org/keys/nginx-keyring.gpg
Добавление репозитория. Он нужен для нахождения пакета на серверах Nginx Unit. Для этого нужно создать файл по пути /etc/apt/sources.list.d/unit.list
. Это можно сделать, если открыть файл одним из редакторов в Ubuntu (vim, nano и так далее). В примере я буду использовать текстовый редактор nano. Выполнив команду ниже мы создадим новый файл.
nano /etc/apt/sources.list.d/unit.list
Далее вставьте туда строки для определения репозитория. Для каждой версии Ubuntu они отличны, так что если ваша версия Ubuntu отличается от примера (Ubuntu 22.04), то их можно найти на официальном сайте по ссылке.
Сохраняем файл, закрываем его и обновляем список пакетов системы командой apt update
(Команда обновляет индекс пакетов в системе Linux или списки пакетов).
apt update
После того как обновление будет завершено устанавливаем Nginx Unit командой apt install <package name>
(Команда apt install <package name>
находит пакет в индексе пакетов операционной системы и загружает их вместе с зависимостями.)
apt install unit
Про apt (apt-get) можно прочитать на русском форуме Ubuntu.
После установки выполняем команду перезапуска сервиса Nginx Unit в операционной системе:
systemctl restart unit
Установку можно проверить командой:
unitd --version
На этом установка закончена. Как видно, Nginx Unit установлен версии 1.30 (последняя версия на время написания статьи). Также ниже версии приведена команда конфигурации, которая может понадобиться для сборки Nginx Unit из исходников.
Другие способы установки
Конфигурация
После того как Nginx Unit будет установлен для работы с ним мы будем использовать ключ config. Эта часть API веб-сервера отвечает за настройку и содержит в себе: слушатели, маршруты, приложения и балансировщики нагрузки.
{
"listeners": {
// Слушатели
},
"routes": [
// Маршруты
],
"applications": {
// Приложения
},
"upstreams": {
// Балансировщики
}
}
Для загрузки конфигурации мы будем обращаться к API по сокету.
Чтобы было удобнее хранить ваш результат рекомендую создавать JSON файлы. Их удобно хранить и не потребуется постоянно выгружать файл конфига. На примере JSON файлов в примере я буду обновлять настройки Nginx Unit. Название файла для примера будет config.json, а команда для загрузки и обновления config.
curl -X PUT --data-binary @config.json --unix-socket /var/run/control.unit.sock http://localhost/config
Пути для загрузки в конфиг
Слушатели
/config/listeners
Маршруты
/config/routes
Приложения
/config/applications
Слушатели
Listeners - это блок, который отвечает за входящий трафик. Веб-сервер может прослушивать Ip адреса и порт. К примеру 127.0.0.1:8080
для использования внутри сервера или *:8080
для получения трафика приходящего на сервер к примеру из клиентского приложения. (В Linux системах можно использовать абстрактные сокеты. Пример unix@abstract_socket
)
Для получения всех слушателей выполните обращение к API через сокет командой. Пример команды ниже:
curl -X GET --unix-socket /var/run/control.unit.sock http://localhost/config/listeners
{ // Объект который мы получим в ответе
"*:8080": { // Слушатель порта 8080
"pass": "routes" // Использование маршрутизации для слушателя
}
}
Команда делает GET запрос к сокету по флагу --unix-socket
который указывает на запущенный Nginx Unit. http://localhost/config/listeners
.
Маршрутизация
Для получения всех маршрутов выполните обращение к API через сокет командой:
curl -X GET --unix-socket /var/run/control.unit.sock http://localhost/config/routes
Если маршруты пусты, вы получите ошибку как на скриншоте ниже.
Маршруты могут быть в виде массивом параметров или массивом ключей
Пример который выполняет все действия из массива при обращении слушателя к routes
{
"listeners": {
"*:80": {
"pass": "routes"
}
},
"routes": [
{
"action": {
"share": "/var/www/example$uri"
}
}
]
}
Указание ключей для массива, чтобы слушатели могли фильтровать трафик:
{
"listeners": {
"*:80": {
"pass": "routes/http"
},
"*:443": {
"pass": "routes/https",
"tls": {
"certificate": "bundle"
}
}
},
"routes": {
"http": {
"action": {
"share": "/var/www/example$uri"
}
},
"https": {
"action": {
"share": "/var/www/example_secure$uri"
}
},
}
}
Приложения и языковые модули
Список поддерживаемых языков программирования для запуска приложений
Go
JavaScript (Node.js)
Java
Perl
PHP
Python
Ruby
Также поддерживаются собранные бинарные файлы. В этой статье рассматриваться это не будет.
Для получения всех приложений выполните обращение к API через сокет командой:
curl -X GET --unix-socket /var/run/control.unit.sock http://localhost/config/applications
Пример использования приложения на PHP. Он запускает 20 процессов на порту 80 используя PHP модуль. Для того чтобы его установить требуется выполнить команду:
apt install unit-php
{
"listeners": {
"*:80": {
"pass": "routes"
}
},
"applications": {
"blogs": {
"type": "php",
"processes": 20,
"root": "/var/www/blogs/scripts/"
}
}
}
Это был самый простой пример, но каждое приложение имеет дополнительные ключи, которые нужно гибко подстраивать. Подробнее про приложения можно прочитать в документации.
Простое приложение
Создадим файл index.html. Для этого откройте текстовый редактор
nano /var/www/example/index.html
и вставьте строки
<!DOCTYPE html>
<html>
<head>
<title>Welcome to NGINX Unit!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to NGINX Unit!</h1>
<p>If you see this page, the NGINX Unit web server is successfully
installed and working. Further configuration is required.
</p>
<p>For online documentation and support, please refer to
<a href="https://unit.nginx.org/">unit.nginx.org</a>.<br/>
</p>
<p><em>Thank you for using NGINX Unit.</em></p>
</body>
</html>
Создайте файл config.json и вставьте строки, который ниже:
{
"listeners": {
"*:80": {
"pass": "routes"
}
},
"routes": [
{
"action": {
"share": "/var/www/example$uri"
}
}
]
}
Загрузите файл конфигурации командой:
curl -X PUT --data-binary @config.json --unix-socket /var/run/control.unit.sock http://localhost/config
Обратитесь к серверу по 80 порту (HTTP) http://<имя вашего домена>:80
:80 - не обязательный параметр, при явной вставке указывает на порт :80 (HTTP)
Но поскольку HTTP соединение не является безопасным следующий пункт показывает как подключить сертификаты и активировать HTTPS.
Подключение сертификатов
Загрузка TLS сертификатов в NGINX UNIT выполняется просто, так же как и конфигурация по API. Для этого полученные сертификаты, сгенерированные к примеру при помощи certbot, склеиваются в один и передаются как единый файл:
cat cert.pem ca.pem key.pem > bundle.pem
Bundle.pem - конечный файл, который и есть сертификат для загрузки в NGINX UNIT. После чего мы делаем запрос к Unit в который передаём bundle.pem
:
curl -X PUT --data-binary @bundle.pem --unix-socket /var/run/control.unit.sock http://localhost/certificates/bundle
Путь для загрузки сертификата /certificates/<name of certificate>
Здесь мы уже использует PUT запрос для обновления списка сертификатов. Название сертификата, которое мы использовали при склеивании не имеет значение, поскольку при загрузке мы указываем новое. Его мы и будем использовать в нашем конфиге. Пример такого файла конфигурации:
{
"listeners": {
"*:443": { // Использование 443 порта для активации HTTPS
"pass": "routes",
"tls": { // Использование сертификата
"certificate": "bundle" // Имя сертификата, который вы загрузили
}
}
}
}
Удаление сертификата проходит так же как и загрузка, но с использованием DELETE вместо PUT в запросе
Сбор логов и статистики
Статистика и health check
Сделав GET запрос к API можно получить информацию о подключениях, запросах, приложениях.
curl -X GET --unix-socket /var/run/control.unit.sock http://localhost/status
А теперь чуть подробнее по каждому из ключей:
Подключения (connections) содержат 4 параметра:
accepted - Количество подключений за время жизни текущего сокета Nginx Unit
active - Текущее количество подключений
idle - Количество незанятый соединений
closed - Количество закрытых подключений за время жизни текущего сокета Nginx Unit
Запросы (requests) содержат единственный ключ total, который отображает Общее количество запросов не связанный с API веб-сервера, за время существования сокета
Приложения (Applications) содержит информацию по каждому приложению. Пример wordpress из официальной документации:
{
"wp": {
"processes": {
"running": 14, // Количество запущенных процессов
"starting": 0, // Стартующие процессы
"idle": 4 // Бездействующие процессы
},
"requests": {
"active": 10 // Подобен запросам, но содержит информацию только
} // по приложению
}
}
Эта вся статистика, которую предоставляет Nginx Unit, тем не менее она краткая и позволяет мониторить всё вместе и по каждому приложению отдельно.
Бонус
Как видно на картинке выше, мы можем выгружать данных из веб-сервера в JSON формате, что может быть полезно для анализа. После этого можно настроить CRON на сервере, для получения данных через заданный промежуток времени.
Логи
По стандарту логи Nginx Unit попадают в файл по пути /var/log/unit.log
. Там содержаться данный по запуску, ошибкам и информации работы веб-сервера. Пример:
2023/06/07 09:48:34 [notice] 266515#266515 no modules matching: "/usr/lib/unit/modules/*.unit.so" found
2023/06/07 09:48:34 [info] 266514#266514 controller started
2023/06/07 09:48:34 [notice] 266514#266514 process 266515 exited with code 0
2023/06/07 09:48:34 [info] 266517#266517 router started
2023/06/07 09:48:34 [info] 266517#266517 OpenSSL 3.0.2 15 Mar 2022, 30000020
2023/06/07 09:49:34 [notice] 266514#266514 process 266516 exited with code 0
2023/06/07 09:49:34 [notice] 266514#266514 process 266517 exited with code 0
2023/06/07 09:49:34 [info] 266834#266834 discovery started
2023/06/07 09:49:34 [notice] 266834#266834 no modules matching: "/usr/lib/unit/modules/*.unit.so" found
2023/06/07 09:49:34 [info] 266833#266833 controller started
2023/06/07 09:49:34 [notice] 266833#266833 process 266834 exited with code 0
В данном примере nginx unit при инициализации подгружает языковые модули, затем обрабатывает роутинг.
Проблемы при работе с Nginx Unit
Отсутствие нужных модулей, а точнее нужных Вам версий. К примеру версия 1.30.0 не имеет поддержку версии PHP 7.4, которая на момент написания статьи всё ещё активно используется, поэтому придётся делать сборку вручную или использовать docker контейнеры.
Использование curl с параметром -d вместо --data-binary. Здесь проблема явна при загрузке сертификатов. Новички в Linux могут принять пример использования флага -d для загрузки JSON, но при загрузке сертификатов столкнуться с проблемой и не поймут в чём дело.
Заключение
В заключение могу сказать, что использование NGINX UNIT понижает порог входа для новичков, которые хотят разворачивать веб-приложения. Он понятный, так как оперирует JSON и использует REST API. Но это не отменяет того, что Unit является мощным инструментом, который до сих пор развивается и восполняет пробелы и устраняет проблемы своего старшего брата веб-сервера NGINX.
Комментарии (4)
optimalcity
09.06.2023 15:50А нету хорошего свежего обзора фич Nginx Unit и бенчмарков?
pavlusha311245 Автор
09.06.2023 15:50Один из последних бенчмарков, которые я встречал, это статья на Хабре о сравнении производительности PHP FPM, Nginx Unit и Laravel Octane на русском. Возможно Вам это поможет :)
Но отмечу, что информации на русском языке по Nginx Unit не так много как хотелось бы. Я не видел, чтобы кто-то выпускал обзор каждой версий с замерением скорости работы и новых фич. Ссылка которая точно может дать сейчас информацию это официальный сайт с анонсами версий.
Спасибо за идею. Я подумаю о выпуске статей на Хабр по новым версиям.
Amadey17
Спасибо за статью. Кое-что новенькое для себя открыл.
pavlusha311245 Автор
Спасибо за оценку статьи. :)