Gunicorn — автономный веб-сервер с обширной функциональностью, предоставленной в удобном виде. Он изначально поддерживает различные фреймворки и адаптеры, что делает его чрезвычайно простой в использовании прямой заменой для многих серверов разработки.
Технически Gunicorn работает подобно Unicorn, популярному веб-серверу приложений Ruby. Они оба используют так называемую pre-fork модель (это значит, что главный процесс управляет инициированными рабочими процессами различного типа, создает сокеты и соединения, и т.п.).
Особенности сервера Gunicorn:
- Запускает любое приложение (и фреймворк) WSGI (Web Server Gateway Interface) Python.
- Служит заменой серверам Paster/Pyramid (сервер разработки Django), web2py и т.п.
- Поставляется с различными конфигурациями и типами процессов.
- Автоматически управляет процессами.
- Поддерживает HTTP/1.0 и HTTP/1.1 с помощью синхронных и асинхронных процессов.
- Поддерживает SSL.
- Расширяется с помощью специальных точек входа.
WSGI (Web Server Gateway Interface) — интерфейс между веб-сервером и самим Python-приложением. Он устанавливает стандартное соединение между различными серверами и приложениями (фреймворками), что обеспечивает их взаимозаменяемость в случае необходимости (например, переход от среды разработки к производственной среде), что очень важно в настоящее время.
Как уже было сказано, веб-серверам, запущенным на WSGI, необходим объект приложения. Для большинства фреймворков и приложений он выглядит так: wsgi.py
содержит и предоставляет объект приложения (или callable), который будет использоваться сервером.
Пример wsgi.py
:
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return ["Hello!"]
Каждый раз, когда поступает запрос, сервер использует этот callable приложения, чтобы запустить его обработчики запросов (например, контроллеры), анализируя URL.
sudo pip3 install gunicorn
Чтобы приложение обслуживалось, выполните:
gunicorn [опция] [опция2] .. [файл wsgi]
Чтобы запустить сервер, используйте следующее:
gunicorn -b 0.0.0.0:8080 wsgi
Это запустит сервер в приоритетном режиме. Чтобы отключить его, нажмите клавиши CTRL + C.
Чтобы запустить сервер в фоновом режиме, выполните следующую команду:
gunicorn -b 0.0.0.0:8080 wsgi &
Запуская приложение в фоновом режиме, используйте менеджер процессов (например, htop
), чтобы прервать его.
Пример запуска Django-приложения:
gunicorn main.wsgi -w 4 --timeout=600 -b 0.0.0.0:8000 --chdir=/app
В целом, считается, что приложения зависят скорее от I/O, чем от CPU. Это значит, что узкое место вызвано не вычислительной мощностью виртуального сервера, а диском. Идея такова: пока один процесс занят дисковыми операциями, другой все еще использует CPU для обработки запросов.
Потому рекомендуемое количество процессов, как правило, вычисляется по следующей формуле:
# (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
:
# Синтаксис: gunicorn --workers=[количество_процессов]
# Пример: gunicorn --workers=5
Примечание: такой сценарий не сработает с неблокируемыми процессами.
Связывание сокетов выполняется следующим образом:
# Синтаксис: gunicorn -b [адрес:порт]
# Пример: gunicorn -b 127.0.0.1:8080
Примечание: когда приложение прослушивает входящие соединения на 127.0.0.1
, доступ к нему можно получить только локально. При использовании 0.0.0.0
, оно также будет принимать соединения извне.
Gunicorn предоставляет возможность использовать разные типы процессов. В большинстве случаев используется sync
— стандартный процесс, установленный по умолчанию и не требующий подробной настройки.
Что касается других процессов — имейте в виду, их необходимо установить как зависимости.
# Синтаксис: gunicorn -k [процесс]
# Пример: gunicorn -k sync
# или: gunicorn -k gevent
Доступные типы процессов:
sync
eventlet
gevent
tornado
Чтобы изменить количество одновременных подключений для процессов Eventlet и Gevent:
# Синтаксис: gunicorn -k [процесс] --worker-connections [количество]
# Пример: gunicorn -k gevent --worker-connections 1001
Чтобы явно определить файл для ведения журнала доступа:
# Синтаксис: gunicorn --log-file [файл]
# Пример: gunicorn --log-file error_logs.log
По умолчанию данная опция имеет значение None
.
Чтобы указать файл для ведения журнала ошибок, используйте:
# Синтаксис: gunicorn --access-logfile [файл]
# Пример: gunicorn --access-logfile acclogs
Это необходимо для повышения степени детализации результата, выведенного журналами ошибок. Доступные уровни:
debug
info
warning
error
critical
# Синтаксис: gunicorn --log-level [уровень]
# Пример: gunicorn --log-level error
При использовании утилит отслеживания процессов (например, top
) данная настройка может быть очень полезной, так как позволяет дать процессу более содержательное имя.
# Синтаксис: gunicorn --name [имя]
# Пример: gunicorn --name my_application