Поиск по сайту:

Как развернуть приложения Python WSGI с помощью HTTP-сервера Gunicorn за Nginx


Введение

Возможно, вас соблазнила статья о сравнении веб-серверов Python, или тот факт, что вы просто переросли свой текущий стек развертывания приложений. Вы заинтересованы в том, чтобы узнать больше о Gunicorn Web Server и хотите узнать, как с самого начала тщательно развернуть приложение Python.

В этой статье DigitalOcean наша цель — помочь вам со всем вышеперечисленным, а затем и с некоторыми другими. Мы начнем с расширения наших знаний об отличном HTTP-сервере Gunicorn WSGI и продолжим развертывание веб-приложений Python WSGI, созданных на основе различных популярных фреймворков.

Глоссарий

1. О Gunicorn и Nginx

  1. Гуникорн
  2. Развертывание веб-приложения с помощью Nginx

2. Подготовка вашей капли к производству

  1. Обновление операционной системы по умолчанию
  2. Настройка Python, pip и virtualenv
  3. Создание виртуальной среды (Python)
  4. Скачивание и установка Gunicorn
  5. Скачивание и установка Nginx

3. Обслуживание веб-приложений Python с помощью Gunicorn

  1. WSGI
  2. Объект приложения WSGI (вызываемый): wsgi.py
  3. Запуск сервера
  4. Настройка и оптимизация Gunicorn
  5. Настройка Nginx
  6. Разные советы и предложения

О Gunicorn и Nginx

Гуникорн

Gunicorn — это автономный сервер веб-приложений WSGI, который предлагает множество функций. Он изначально поддерживает различные платформы со своими адаптерами, что делает его чрезвычайно простой в использовании заменой многих серверов разработки, которые используются во время разработки.

Технически принцип работы Gunicorn очень похож на успешный веб-сервер Unicorn для приложений Ruby. Они оба используют так называемую модель pre-fork. Это, по сути, поручает центральному главному процессу [Gunicorn] управлять рабочими процессами, создавать сокеты и привязки и т. д.

Особенности сервера Gunicorn

  • Запускает любое веб-приложение WSGI Python (и фреймворк)
  • Может использоваться в качестве замены для Paster (Pyramid), Django’s Development Server, web2py и т. д.
  • Поставляется с различными типами рабочих и конфигурациями
  • Автоматически управляет рабочими процессами
  • Поддержка HTTP/1.0 и HTTP/1.1 (Keep-Alive) через синхронные и асинхронные рабочие процессы
  • Поддерживает SSL
  • Расширяется с помощью крючков
  • Поддержка Python 2.6+ и 3.x

Развертывание веб-приложения с помощью Nginx

Nginx — это очень высокопроизводительный веб-сервер/(обратный)-прокси. Он достиг своей нынешней популярности благодаря небольшому весу, относительной простоте работы и легкости расширения (с надстройками/плагинами). Благодаря своей архитектуре он способен обрабатывать множество запросов (практически неограниченных), с которыми, в зависимости от загрузки вашего приложения или веб-сайта, может быть очень сложно справиться, используя некоторые другие, более старые альтернативы.

Помните: технически \обработка соединений означает, что вы не должны прерывать их и иметь возможность обслуживать их чем-то. Вам по-прежнему необходимо, чтобы ваше приложение и база данных работали хорошо, чтобы Nginx обслуживал клиентов *отклики, которые не являются ошибками. Сообщения.

Зачем использовать Nginx в качестве обратного прокси перед сервером приложений?

Многие фреймворки и серверы приложений (включая Gunicorn) могут обслуживать статические файлы (например, javascript, css, изображения и т. д.) вместе с ответами. Однако лучше всего позволить (обратному прокси) серверу, такому как Nginx, справиться с задачей обслуживания этих файлов и управления соединениями (запросами). Это снимает большую нагрузку с серверов приложений, обеспечивая гораздо лучшую общую производительность.

По мере роста вашего приложения вы захотите оптимизировать его, а когда придет время, распределить его по серверам (VPS), чтобы иметь возможность обрабатывать больше подключений одновременно (и в целом иметь более надежную архитектуру). Наличие обратного прокси-сервера перед вашими серверами приложений поможет вам с самого начала.

Расширяемость Nginx (например, встроенное кэширование вместе с аварийным переключением и другими механизмами) также является отличным достижением, которое приносит пользу веб-приложениям в отличие от (более простых) серверов приложений.

Пример базовой архитектуры сервера:

Client Request ----> Nginx (Reverse-Proxy)
                        |
                       /|\                           
                      | | `-> App. Server I.   127.0.0.1:8081
                      |  `--> App. Server II.  127.0.0.1:8082
                       `----> App. Server III. 127.0.0.1:8083

Примечание. См. раздел Настройка и оптимизация Gunicorn, чтобы узнать о количестве используемых серверов/воркеров.

Подготовка вашей капли к производству

В этом разделе мы собираемся подготовить нашу виртуальную машину к производству (т. е. к развертыванию нашего приложения).

Мы начнем с:

  • обновление операционной системы по умолчанию
  • загрузка и установка общих инструментов Python (например, pip, virtualenv)
  • создание виртуальной среды для приложения (внутри которого находятся его зависимости, такие как Gunicorn)

Примечание. Инструкции, приведенные здесь, краткие. Чтобы узнать больше, ознакомьтесь с нашей статьей с практическими рекомендациями по pip и virtualenv: Общие инструменты Python: использование virtualenv, установка с помощью Pip и управление пакетами.

Обновление операционной системы по умолчанию

Примечание. Мы будем выполнять следующую настройку и подготовку для новой капли с использованием последних версий операционных систем. Теоретически у вас не должно возникнуть проблем с их использованием на вашем VPS. Однако, если вы уже активно его используете, настоятельно рекомендуем перейти на новую систему.

Чтобы убедиться, что у нас есть последние доступные версии приложений по умолчанию, нам необходимо обновить нашу систему.

Для систем на основе Debian (например, Ubuntu, Debian) выполните следующее:

aptitude    update
aptitude -y upgrade

Для систем на базе RHEL (например, CentOS) выполните следующее:

yum -y update

Настройка Python, pip и virtualenv

Примечание для пользователей CentOS/RHEL:

CentOS/RHEL по умолчанию представляет собой очень компактный сервер. Его набор инструментов, который, вероятно, будет устаревшим для ваших нужд, предназначен не для запуска ваших приложений, а для питания системных инструментов сервера (например, YUM).

Чтобы подготовить вашу систему CentOS, необходимо настроить Python (то есть скомпилировать из исходного кода), а pip/virtualenv необходимо установить с помощью этого интерпретатора.

Чтобы узнать, как настроить Python 2.7.6 и 3.3.3 в CentOS 6.4 и 5.8 с помощью pip и virtualenv, см. статью Как настроить Python 2.7.6 и 3.3.3 в CentOS.

В Ubuntu и Debian последняя версия интерпретатора Python, которую вы можете использовать, поставляется по умолчанию. Это оставляет нам только ограниченное количество дополнительных пакетов для установки:

  • python-dev (инструменты разработки),
  • pip (для управления пакетами),
  • virtualenv (для создания изолированных виртуальных сред).

Python-разработчик:

python-dev – это пакет уровня операционной системы, который содержит расширенные средства разработки для создания модулей Python.

Выполните следующую команду, чтобы установить python-dev с помощью aptitude:

aptitude install python-dev

пункт:

pip — это менеджер пакетов, который поможет нам установить необходимые пакеты приложений.

Выполните следующие команды для установки pip:

curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python -
curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python -
export PATH="/usr/local/bin:$PATH"

Вам могут понадобиться привилегии sudo.

виртуальная среда:

Лучше всего содержать приложение Python в его собственной среде вместе со всеми его зависимостями. Среду лучше всего можно описать (простыми словами) как изолированное место (каталог), где все находится. Для этого используется инструмент под названием virtualenv.

Запустите следующее, чтобы установить virtualenv с помощью pip:

sudo pip install virtualenv

Создание автономной виртуальной (Python) среды

Подготовив все необходимые инструменты, мы можем создать среду для развертывания нашего приложения.

Помните: если у вас нет виртуальной среды на вашей машине разработки (локальной) для вашего проекта, вам следует подумать о ее создании и перемещении вашего приложения (и его зависимостей) внутрь.

Давайте начнем с создания папки, которая будет содержать как виртуальную среду, так и модуль вашего приложения:

Вы можете использовать любое имя здесь, чтобы удовлетворить ваши потребности.

mkdir my_app

Мы можем продолжить, войдя в эту папку и создав внутри новую виртуальную среду:

Вы также можете выбрать любое имя для своей виртуальной среды.

cd my_app
virtualenv my_app_venv

Давайте создадим там новую папку, в которую также будет помещен ваш модуль приложения Python:

Это папка, в которой будет находиться модуль вашего приложения.

mkdir app

И активируйте интерпретатор внутри виртуальной среды, чтобы использовать его:

Обязательно используйте имя, которое вы выбрали для своей виртуальной среды, если вы выбрали что-то другое, чем \my_app_venv.

source my_app_venv/bin/activate

В итоге вот как должен выглядеть ваш основной каталог развертывания приложения:

my_app              # Main Folder to Contain Everything Together
  |
  |=== my_app_venv  # V. Env. folder with the Python Int.
  |=== app          # Your application module
  |..
  |.

Загрузка и установка Gunicorn

Всегда рекомендуется размещать все элементы, связанные с приложением, вместе, насколько это возможно, внутри виртуальной среды. Поэтому скачаем и установим туда Gunicorn.

Если вы не работаете внутри среды, Gunicorn будет установлен глобально (т.е. доступен для всей системы). Это не рекомендуется. Всегда выбирайте использование virtualenv.

Чтобы установить Gunicorn с помощью pip, выполните следующее:

pip install gunicorn

Скачиваем и устанавливаем Nginx

Примечание для пользователей CentOS/RHEL:

Приведенные ниже инструкции не будут работать в системах CentOS. Пожалуйста, ознакомьтесь с инструкциями для CentOS здесь.

Выполните следующую команду, чтобы использовать системный менеджер пакетов по умолчанию aptitude для установки Nginx:

sudo aptitude install nginx

Для запуска Nginx вы можете использовать следующее:

sudo service nginx start

Чтобы остановить Nginx, вы можете использовать следующее:

sudo service nginx stop

Чтобы перезапустить Nginx, вы можете использовать следующее:

После каждой перенастройки Nginx требуется перезагрузка или перезагрузка, чтобы новые настройки вступили в силу.

sudo service nginx restart

Примечание. Чтобы узнать больше о Nginx в Ubuntu, обратитесь к нашей статье: Как установить Nginx в Ubuntu 12.04.

Обслуживание веб-приложений Python с помощью Gunicorn

В этом разделе мы увидим, как приложение WSGI работает с Gunicorn. Этот процесс состоит из предоставления серверу вызываемого приложения WSGI (например, application=(..)) в качестве точки входа.

WSGI

Короче говоря, WSGI — это интерфейс между веб-сервером и самим приложением. Он существует для обеспечения стандартизированного способа работы различных серверов и приложений (фреймворков) друг с другом, обеспечивая при необходимости взаимозаменяемость (например, переход от среды разработки к рабочей среде), что является обязательной необходимостью в настоящее время.

Примечание. Если вам интересно узнать больше о веб-серверах WSGI и Python, ознакомьтесь с нашей статьей: Сравнение веб-серверов для веб-приложений на основе Python.

Объект приложения WSGI (вызываемый): wsgi.py

Как упоминалось выше, веб-серверы, работающие на WSGI, нуждаются в объекте приложения (то есть вашего приложения).

В большинстве фреймворков и приложений он состоит из:

  • Файл wsgi.py, содержащий и предоставляющий объект приложения (или вызываемый объект), который будет использоваться сервером.

Мы начнем с создания примерного wsgi.py для использования с Gunicorn.

Вы можете выбрать любое имя вместо \wsgi.py. Тем не менее, это те, которые обычно используются (например, Django).

Начнем с создания файла wsgi.py, который будет содержать базовое приложение WSGI.

Выполните следующую команду, чтобы создать wsgi.py с помощью текстового редактора nano:

nano wsgi.py

Давайте продолжим перемещать (копировать/вставлять) базовый код приложения WSGI внутрь (который следует заменить кодом вашего собственного приложения, вызываемым для производства):

def application(env, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return ["Hello!"]

Это файл, который включается сервером, и каждый раз, когда приходит запрос, сервер использует это вызываемое приложение для запуска обработчиков запросов приложения (например, контроллеров) после анализа URL-адреса (например, mysite.tld/controller/method/ переменная).

После размещения кода приложения нажмите CTRL+X, а затем подтвердите с помощью Y, чтобы сохранить этот файл в папке «my_app» вместе с виртуальной средой и модулем приложения, содержащим ваше фактическое приложение.

Примечание. Это приложение WSGI является самым простым примером такого рода. Вам нужно будет заменить этот блок кода, чтобы включить собственный объект приложения из модуля приложения.

Когда мы закончим, вот как должен выглядеть ваш основной каталог развертывания приложения:

my_app              # Main Folder to Contain Everything Together
  |
  |=== my_app_venv  # V. Env. folder with the Python Int.
  |=== app          # Your application module
  |
  |--- wsgi.py      # File containing application callable
  |..
  |.

Запуск сервера

Чтобы начать обслуживание вашего приложения, вам просто нужно выполнить:

gunicorn [option] [option] .. [wsgi file]

Выполните следующее, чтобы запустить сервер:

gunicorn -b 0.0.0.0:8080 wsgi

Это запустит сервер на переднем плане. Если вы хотите остановить его, нажмите CTRL+C.

Чтобы запустить сервер в фоновом режиме, выполните следующее:

gunicorn -b 0.0.0.0:8080 wsgi &

Когда вы запускаете приложение в фоновом режиме, вам нужно будет использовать диспетчер процессов (например, htop), чтобы убить (или остановить) его.

Настройка и оптимизация Gunicorn

Примечание. Ниже приведены некоторые из наиболее часто используемых параметров конфигурации и оптимизации. Чтобы узнать обо всех доступных параметрах, ознакомьтесь с официальной документацией по обзору конфигурации Gunicorn.

Как упоминалось ранее, Gunicorn легко настраивается, и очень легко изменить все необходимые параметры по своему усмотрению.

[!] Важно: Все перечисленные ниже настройки и параметры конфигурации должны быть связаны (ставить друг за другом) для запуска пушкикорна и сервера вашего приложения. Вы не можете изменить ни один из параметров после запуска сервера. Какой бы параметр или параметры вы ни использовали, за ними должен следовать файл wsgi, содержащий точку входа в ваше приложение.

Пример:

# Simply running the server (as shown above):
gunicorn -b 0.0.0.0:8080 wsgi

# Running the server with five workers:
gunicorn -b 0.0.0.0:8080 --workers=5 wsgi

Количество рабочих

В целом считается (и принято), что приложения скорее привязаны к вводу-выводу, чем к процессору. Это означает, что узкое место вызвано не вычислительной мощностью вашего виртуального сервера, а дисками. Идея такова: когда один работник занят дисковыми операциями, другой все еще использует ЦП, обрабатывая запросы.

Таким образом, предлагаемое количество рабочих обычно определяется по следующей простой формуле:

# (2 Workers * CPU Cores) + 1
# ---------------------------
# For 1 core  -> (2*1)+1 = 3
# For 2 cores -> (2*2)+1 = 5
# For 4 cores -> (2*4)+1 = 9

Вы можете указать количество рабочих, передав аргумент --workers=[n].

Использование:

# Example: gunicorn --workers=[number of workers]
gunicorn --workers=5

Примечание. Приведенный выше сценарий не относится строго к неблокирующим рабочим процессам.

Настройки сокета

Привязка сокетов работает следующим образом:

# Example: gunicorn -b [address:port]
gunicorn -b 127.0.0.1:8080

Примечание. Если приложение настроено на прослушивание входящих подключений на 127.0.0.1, доступ к нему будет возможен только локально. Однако если вы используете 0.0.0.0, он также будет принимать подключения из внешних.

Выбор типа работника

Gunicorn, как мы уже говорили, предлагал возможность работать с различными типами работников.

Для большинства развертываний стандартного рабочего типа — синхронизации — будет достаточно, и он поставляется по умолчанию, поэтому не требует какой-либо явной настройки.

Обратите внимание, что для других рабочих процессов вам нужно будет установить их в качестве зависимостей.

Использование:

# Example: gunicorn -k [worker]
gunicorn -k sync    # or;
gunicorn -k gevent  # ..

Доступные типы:

  • синхронизировать
  • событие
  • получить
  • торнадо

Количество одновременных подключений для Eventlet/Gevent

Чтобы изменить количество одновременных подключений для воркеров Eventlet и Gevent:

# Example: gunicorn -k [worker] --worker-connections [number]
gunicorn -k gevent --worker-connections 1001

Журналы доступа

Если вы хотите явно указать файл для записи журналов доступа:

# Example: gunicorn --access-logfile [file]
gunicorn --access-logfile acclogs

По умолчанию для этого параметра установлено значение Нет.

Журналы ошибок

Используйте этот параметр, чтобы указать файл для записи журналов ошибок.

# Example: gunicorn --log-file [file]
gunicorn --log-file error_logs.log

Уровень журнала

Это используется для установки степени детализации выходных данных журнала ошибок. Возможные варианты:

  • отладка
  • информация
  • предупреждение
  • ошибка
  • критично

Использование:

 # Example: gunicorn --log-level [level]
 gunicorn --log-level error

Именование процессов

Если вы используете утилиты, такие как top, для мониторинга своих процессов, вы можете использовать этот параметр, чтобы дать им более осмысленное имя, которое должно помочь вам в выполнении задачи.

# Example: gunicorn --name [name]
gunicorn --name my_application

Настройка Nginx

Узнав о настройке и запуске Gunicorn, теперь нам нужно сделать то же самое с Nginx, чтобы поговорить с сервером Gunicorn, на котором запущено приложение. Для этого нам нужно изменить файл конфигурации Nginx: nginx.conf

Выполните следующую команду, чтобы открыть \nginx.conf и отредактируйте его с помощью текстового редактора nano:

sudo nano /etc/nginx/nginx.conf

После этого вы можете заменить файл на следующий пример конфигурации, чтобы заставить Nginx работать как обратный прокси-сервер, взаимодействующий с вашим приложением.

Примечание. Чтобы узнать о включении поддержки SSL, сначала прочитайте эту статью: Создание сертификата SSL в Nginx.

Пример конфигурации для веб-приложений:

worker_processes 1;

events {

    worker_connections 1024;

}

http {

    sendfile on;
    
    gzip              on;
    gzip_http_version 1.0;
    gzip_proxied      any;
    gzip_min_length   500;
    gzip_disable      "MSIE [1-6]\.";
    gzip_types        text/plain text/xml text/css
                      text/comma-separated-values
                      text/javascript
                      application/x-javascript
                      application/atom+xml;

    # Configuration containing list of application servers
    upstream app_servers {
    
        server 127.0.0.1:8080;
        # server 127.0.0.1:8081;
        # ..
        # .
    
    }

    # Configuration for Nginx
    server {
    
        # Running port
        listen 80;

        # Settings to serve static files 
        location ^~ /static/  {
        
            # Example:
            # root /full/path/to/application/static/file/dir;
            root /app/static/;
        
        }
        
        # Serve a static file (ex. favico)
        # outside /static directory
        location = /favico.ico  {
        
            root /app/favico.ico;
        
        }

        # Proxy connections to the application servers
        # app_servers
        location / {
        
            proxy_pass         http://app_servers;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        
        }
    }
}

Когда вы закончите изменение конфигурации, нажмите CTRL+X и подтвердите Y, чтобы сохранить и выйти. Вам нужно будет перезапустить Nginx, чтобы изменения вступили в силу.

Выполните следующее, чтобы перезапустить Nginx:

sudo service nginx stop
sudo service nginx start

Примечание. Чтобы узнать больше о Nginx, обратитесь к нашей статье: Как настроить веб-сервер Nginx на VPS.

Разные советы и предложения

Брандмауэр:

  • Настройка брандмауэра с помощью таблиц IP-адресов

Защита SSH:

  • Как защитить SSH с помощью fail2ban в Ubuntu
  • Как защитить SSH с помощью fail2ban в CentOS 6

Создание оповещений:

  • Как отправлять оповещения по электронной почте на CentOS VPS для мониторинга системы

Ежедневный мониторинг и просмотр журналов доступа к серверу:

  • Как установить и использовать Logwatch Log Analyzer и Reporter

Прислано: