@Lord_Prizrak
Программист, электронщик

Веб-приложение написано. Что дальше?

Написано что-то вроде cms на Flask-е. Заказчиков несколько, "сайтов" тоже несколько.
Не могу понять как правильно это дело развернуть в полный рост на одной VPS.
В большинстве своём рекомендуют nginx, который смотрит во внешку, и запросы дальше передаёт уже отдельным экземплярам приложения, которые запущены в своих виртуальных окружениях, точнее не самим экземплярам, а именно экземплярам вэб-сервера, например gunicorn или uwsgi, который уже передаёт запрос дальше приложению.

Зачем так усложнено? Или есть какое-то обоснование для этого?

Ведь для такой связки надо править конфиги всех программ в связке (nginx + по одному для каждого экземпляра веб-сервера, и конфиги каждого приложения). Или есть какие-то инструменты для автоматизации сего безобразия? Это первое.
Ещё дубляж приложения и его окружения на диске и в памяти для каждого экземпляра. Второе.
При обновлении приложения, необходимо обновлять каждый экземпляр. Третье.
И т.д. и т.п.

Или просто нет альтернатив?

P.S. Не пинайте сильно я первый раз этим занимаюсь.
  • Вопрос задан
  • 801 просмотр
Решения вопроса 1
@bromzh
Drugs-driven development
.
    _______                         ________
   |       |                       |        |
   |   n   | -> site1.com ->|  |-->| uwsgi1 |-->|   |--> app1 for site1
   |   g   |                |  |   |________|   |   |
-->|   i   | -> site2.com ->|->|    ________    |-->|--> app2 for site2
   |   n   |                |  |   |        |   |   |
   |   x   | -> site3.com ->|  |-->| uwsgi2 |-->|   |--> app3 for site3
   |_______|                       |________|

Это примерная общая структура деплоя нескольких питоновских wsgi-приложений.

1) Nginx ставят вперёд в основном для:
a) отдачи статики
b) балансировки нагрузки
Он быстрый, надёжный, статику отдаёт лучше, чем uwsgi, плюс, можно настроить всякие https. Однако, nginx не умеет запускать питоновские приложения. Для этого он проксирует запрос на wsgi-совместимый сервер.
2) В wsgi-сервере запускаются все доступные питоновские приложения. Uwsgi можно довольно гибко конфигурировать, посмотри оф доки. Одной из классных штук является emperor-mode: uwsgi может сканировать папку на наличие конфигов и автоматом подхватывать питоновские приложения. Обычно создаётся 1 папка, а каждое wsgi-приложение просто делает симлинк с конфигом в эту папку.
3) Uwsgi можно запустить как через обычный tcp-сокет, так и через unix-сокет. Что ты выберешь, то и надо будет указывать в конфиге nginx
4) Uwsgi лучше запускать через supervisord. Он позволяет перезапускать приложение при падении, гибко настраивать запуск похожих демонов, перенаправлять stdout/stderr, настраивать переменные окружения и т.д.. Опять же, смтри доки. В конфиге прописываешь, как у тебя будет запускаться uwsgi и какой конфиг/папку с конфигами uwsgi будет читать.
5) Если сервер имеет N ядер, то имеет смысл запустить N-1 штук процессов uwsgi на разных портах/с разными sock-файлами. Тогда nginx сможет балансировать нагрузку между ними. Запускать группу процессов можно либо через супервизор, либо задав настройки в конфиге самого Uwsgi, тут как удобнее. Разница будет лишь в том, что в первом варианте при падении одного uwsgi, остальные будут жить, а во втором случае, перезапустятся все процессы uwsgi (скорее всего).
6) Не надо описывать конфиг каждого uwsgi-сервера в nginx отдельно, для группы есть upstream.
7) Насколько я понимаю, если питоновское приложение 1, то лучше запустить несколько экземпляров uwsgi через супервизор, если их много - запускать несколько штук uwsgi в emperor-mode.

Я точно не помню синтаксис конфигов, но должно получиться что-то похожее на такое:
# Конфиг supervisor:
[program:uwsgi]
numprocs = 3 (для 4-х ядерного серва)
command = uwsgi --emperor /path/to/conf/dir --socket /tmp/uwsgi/uwsgi-%(process_num).sock


Либо так:
# Конфиг  uwsgi: /path/to/conf/default.ini
[uwsgi]
socket = /tmp/sockets/uwsgi-%(vassal_name).sock

# Конфиг супервизора
[program:uwsgi]
command = uwsgi --emperor /path/to/conf/dir ----vassals-include path/to/conf/default.ini


В любом случае, всё это дело потом легко добавляется в nginx:
upstream backend {
    server localhost:8001;  #для tcp-сокетов
    server localhost:8002;

    server unix:/tmp/uwsgi/uwsgi-1.sock; # для unix-сокетов
    server unix:/tmp/uwsgi/uwsgi-2.sock;
}
# А потом просто проксируешь на эту штуку:
server {
    location / {
        listen       80;
        server_name site1.com;
        proxy_pass http://backend;
    }
}

server {
    location / {
        listen       80;
        server_name site2.com;
        proxy_pass http://backend;
    }
}


PS Возможно, если количество питоновских приложух сопоставимо с количеством процессоров, то может будет лучше настроить так: 1 экземпляр uwsgi на 1 приложение. Но я точно не знаю, имеет ли это смысл, надо читать внимательно доки uwsgi и nginx.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
un1t
@un1t
Если вкратце, то ты можешь обойтись без этого и напрямую показывать свое приложение наружу. Но основания для такой архитектуры действительно, есть, это позволяет обслуживать большее количество запросов и как не странно снижает потребление памяти. Подробнее писать лень, полно информации на эту тему.
При обновлении приложения надо только uswgi (или gunicorn) рестартанут и все.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы