Содержание

  1. Введение

  2. Что такое Nginx Unit?

  3. Установка

  4. Конфигурация

    1. Слушатели

    2. Маршрутизация

    3. Приложения и языковые модули

    4. Простое приложение

  5. Сбор логов

  6. Установка сертификатов

  7. Возможные проблемы при работе

  8. Заключение

Введение

Доброго времени суток. Сегодня хочу рассказать про работу с 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
Редактор nano, который ссылается на файл /etc/apt/sources.list.d/unit.list
Редактор nano, который ссылается на файл /etc/apt/sources.list.d/unit.list

Далее вставьте туда строки для определения репозитория. Для каждой версии Ubuntu они отличны, так что если ваша версия Ubuntu отличается от примера (Ubuntu 22.04), то их можно найти на официальном сайте по ссылке.

Репозитории для Nginx Unit для версии Ubuntu 22.04
Репозитории для Nginx Unit для версии 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
Вывод команды unitd --version
Вывод команды 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)


  1. Amadey17
    09.06.2023 15:50

    Спасибо за статью. Кое-что новенькое для себя открыл.


    1. pavlusha311245 Автор
      09.06.2023 15:50

      Спасибо за оценку статьи. :)


  1. optimalcity
    09.06.2023 15:50

    А нету хорошего свежего обзора фич Nginx Unit и бенчмарков?


    1. pavlusha311245 Автор
      09.06.2023 15:50

      Один из последних бенчмарков, которые я встречал, это статья на Хабре о сравнении производительности PHP FPM, Nginx Unit и Laravel Octane на русском. Возможно Вам это поможет :)
      Но отмечу, что информации на русском языке по Nginx Unit не так много как хотелось бы. Я не видел, чтобы кто-то выпускал обзор каждой версий с замерением скорости работы и новых фич. Ссылка которая точно может дать сейчас информацию это официальный сайт с анонсами версий.
      Спасибо за идею. Я подумаю о выпуске статей на Хабр по новым версиям.