Изначально я написал статью «Развертывание Django в Ubuntu с помощью nginx и uWSGI», которая была очень популярна. Это руководство, которое шаг за шагом направляет разработчиков к развертыванию. Хотя, основываясь на этом, желающие разработчики могут понять более подробное содержание, но сама статья не является исчерпывающей. Может быть много новичков, которые прочитали статью и могу только знать, не знаю, почему.
Развертывание Flask очень просто.Поиск в Интернете о том, как развернуть приложения Flask, может найти много информации как на китайском, так и на английском языке, но в основном все они были описаны в нескольких предложениях, что делает многих «новичков» с небольшим опытом очень неуверенно.
Итак, некоторое время назад Гевин тщательно изучил некоторые соответствующие материалы и написал эту подробную статью о развертывании Flask, в которой не только более подробно объясняется развертывание Flask (и расширено на другие веб-фреймворки Python), но также рассматривается описанное выше развертывание Django. , Дополнение статьи в другом измерении. Надеюсь быть полезным для всех.
1. Why Flask+Gunicorn+Nginx
Flask+Gunicorn+Nginx — наиболее часто используемое решение для развертывания Flask.Вы когда-нибудь изучали, почему используется эта комбинация?
1.1 Why?
Flask — это веб-фреймворк, а не веб-сервер. Веб-сервисы, напрямую подтягиваемые Flask, ограничены средой разработки. Рабочая среда недостаточно стабильна и не может выдержать параллелизм большого количества запросов. , для обработки различных запросов необходимо использовать серверное программное обеспечение, такие как Gunicorn, Nginx или Apache, и комбинация Gunicorn+Nginx имеет много преимуществ.С одной стороны, переадресация службы Gunicorn на основе Nginx может дополнить недостатки Служба Gunicorn в некоторых случаях в производственной среде.С другой стороны, если вы делаете веб-сайт, помимо обслуживания, имеет много статических файлов, которые необходимо разместить.В этом сила Nginx, а также то, для чего Gunicorn не подходит. Поэтому для веб-сайтов, разработанных на основе Flask, для развертывания используются Gunicorn и Nginx, что является хорошим выбором.
1.2 Anything More?
1. Зачем вам нужен Nginx для переадресации сервиса Gunicorn?
Nginx является мощным, и использование Nginx дает много преимуществ, но использование Nginx для перенаправления служб Gunicorn направлено на решение проблемы снижения производительности, вызванной «медленным поведением клиента» на сервере; кроме того, при развертывании служб HTTP на Интернет, вы также должны учитывать «быстрый ответ клиента», обработку SSL и высокий уровень параллелизма, и эти проблемы могут быть решены на Nginx, поэтому добавление слоя обратного прокси-сервера Nginx поверх службы Gunicorn является многоцелевым решением для развертывания.
2. Почему возникает проблема снижения производительности сервиса из-за "медленного поведения клиента"?
Связь между сервером и клиентом вкратце делится на три части: запрос, обработка запроса и ответ, то есть клиент инициирует запрос к серверу, сервер отвечает и обрабатывает запрос и возвращает результат запроса в клиент Эти три процесса .
Обычно часть обработки запроса — это расчет сервера, который касается производительности сервера, и обработка более эффективна и стабильна, а часть запроса и ответа имеет много влияющих факторов.Если эти три процесса размещены в одном и том же процессе они обрабатываются синхронно. , если части запроса и ответа занимают много времени, вычислительные ресурсы будут заняты и не могут быть высвобождены вовремя, что приведет к неэффективному использованию вычислительных ресурсов и снижению вычислительной мощности сервер.
Вышеупомянутое «медленное поведение клиента» относится к случаю, когда часть запроса (или ответа) занимает много времени. Gunicorn помещает три вышеупомянутых процесса в один и тот же процесс. Когда происходит «медленное поведение клиента», эффективность очень высока. низкий:
Gunicorn — это программное обеспечение для предварительного разветвления, которое очень эффективно для связи с малой задержкой, такой как балансировка нагрузки или межсервисная связь. Однако недостатком системы предварительного разветвления является то, что каждая коммуникация будет иметь эксклюзивный процесс.Когда запросов к серверу больше, чем процессов, доступных серверу, поскольку на стороне сервера нет больше процессов для ответа на новые запросы, эффективность ответа будет снижена.
Для веб-сайтов или служб, поскольку задержки запросов и ответов неконтролируемы, нам необходимо рассмотреть случай обработки клиентских запросов с высокой задержкой. Эти запросы будут занимать серверный процесс. Когда медленный клиент связывается напрямую со службой, поскольку медленный клиентский запрос будет занимать процесс, количество процессов, доступных для обработки новых запросов, будет уменьшено.Если есть много медленных клиентских запросов, занимающих все процессы, новый запрос может быть только ждать После того, как процесс освобожден, получен ответ. Кроме того, если приложение ожидает более высокий параллелизм, связь между сервером и клиентом должна быть более эффективной, а асинхронная связь будет более эффективной, чем синхронная.
Программное обеспечение асинхронного сервера, такое как Nginx, хорошо справляется с обработкой большого количества запросов с небольшими затратами памяти и процессора. Поскольку они хорошо обрабатывают множество клиентских запросов одновременно, медленные клиентские запросы не сильно на них влияют. Что касается Nginx, то при нынешних общих условиях серверного оборудования легко обрабатывать десятки тысяч запросов одновременно.
Так что это хороший выбор, чтобы заблокировать Nginx перед службой предварительного разветвления для обработки запросов. Nginx может отвечать на клиентские запросы асинхронно и с высоким параллелизмом (медленные клиентские запросы мало влияют на Nginx).Как только Nginx получает запрос, он сразу же перенаправляет его в сервис Gunicorn для обработки, а результат обработки отправляется обратно в заказчик в виде ответа от Nginx end. Таким образом, связь между всем сервером и клиентом изменилась с синхронной связи только через Gunicorn на асинхронную связь на основе Nginx и Gunicorn, а эффективность связи и возможности параллелизма были значительно улучшены.
Для веб-сайтов, помимо ситуаций, описанных выше, также следует учитывать размещение различных статических файлов. К статическим файлам относятся интерфейсные файлы, такие как CSS и JavaScript, а также изображения, видео и различные документы. Поэтому статические файлы могут быть большими или вызываться часто. Функция размещения статических файлов заключается в обеспечении различных статических функций. Нормальная загрузка , предварительный просмотр или загрузка на самом деле являются «медленным поведением клиента», который требует много времени для ответа. Использование Gunicorn для размещения статических файлов также серьезно повлияет на эффективность ответа Gunicorn, и это именно то, в чем хорош Nginx, поэтому размещение статических файлов также выполняется Nginx.
2. Как развернуть сайт Flask
В сочетании с объяснением в предыдущем разделе, как развертывается веб-сайт Flask, также очень ясно:
-
Используйте серверное программное обеспечение (например, Gunicorn), чтобы загрузить приложение, написанное на Flask.
-
Используйте Nginx в качестве обратного прокси-сервера для приложения, подтянутого на предыдущем шаге.
-
Статические файлы, задействованные на веб-сайте, используют Nginx для размещения файлов.
Распространенным серверным программным обеспечением являются Gunicorn и uWSGI.Поскольку Gunicorn прост в использовании и эффективен, настройка Gunicorn для загрузки веб-сайтов Flask чрезвычайно проста, поэтому Gunicorn обычно является наиболее распространенным решением для развертывания веб-сайтов Flask. (Кроме того, лично Гевину также нравится Gunicorn, потому что Gunicorn написан на чистом Python и может быть установлен напрямую по pip, а uwsgi также требует установки дополнительных зависимостей в системе, что особенно просто при использовании с docker. protrude)
Для хостинга статических файлов, поскольку реализация хостинга статических файлов обычно основана на платформе Flask на этапе разработки, когда Gunicorn используется для загрузки веб-сайта Flask, на веб-сайте уже реализована функция хостинга файлов на основе Gunicorn, поэтому настройте Nginx для размещения статических файлов. Когда используется URL-адрес, он может быть напрямую настроен с тем же путем к файлу, что и хостинг на основе Gunicorn, что упрощает логику разработки и развертывания, а также поскольку Nginx является более внешним уровнем, чем Gunicorn, когда клиент запрашивает статические файлы, Nginx напрямую возвращает ответ. Не беспокойтесь о том, что запрос к Gunicorn может повлиять на эффективность сервера.
2.1 Gunicorn
Как Gunicorn развертывает веб-сайт Flask, просто посмотрите официальные файлы Flask или Gunicorn, обычно просто выполните команду, подобную следующей:
/usr/local/bin/gunicorn -w 2 -b :4000 manage:app
скопировать код
2.2 Nginx
Использовать Nginx в качестве обратного прокси-сервера и размещать статические файлы также очень просто. Я предоставляю демоверсию, доступную здесь. Чтобы узнать больше о способах игры, ознакомьтесь с документацией Nginx самостоятельно.
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://localhost:8000/;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /media {
alias /usr/share/nginx/html/media;
}
location /static {
alias /usr/share/nginx/html/static;
}
}
скопировать код
Среди них конфигурация обратного прокси:
location / {
proxy_pass http://localhost:8000/;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
скопировать код
Конфигурация для размещения статических файлов:
location /media {
alias /usr/share/nginx/html/media;
}
location /static {
alias /usr/share/nginx/html/static;
}
скопировать код
Здесь я разместил файлы в двух папках.
3. Развертывание веб-сайта Flask на основе Docker
Преимущество Docker в том, что его можно развернуть один раз и запустить везде.На практике более удобно инкапсулировать описанный выше традиционный метод развертывания в образ Docker, а затем координировать его с Docker Compose для оркестровки сервисов.
3.1 Создайте зеркало веб-сайта Flask
Обычно образ содержит рабочую среду веб-сайта Flask, а затем сервис Gunicorn может использоваться в качестве рабочей команды образа.Например, Dockerfile моего OctBlog написан следующим образом:
# MAINTAINER Gevin <flyhigher139@gmail.com>
# DOCKER-VERSION 18.03.0-ce, build 0520e24FROM python:3.6.5-alpine3.7
LABEL maintainer="flyhigher139@gmail.com"
RUN mkdir -p /usr/src/app && \
mkdir -p /var/log/gunicorn
WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/requirements.txt
RUN pip install --no-cache-dir gunicorn && \
pip install --no-cache-dir -r /usr/src/app/requirements.txt
COPY . /usr/src/app
ENV PORT 8000
EXPOSE 8000 5000
CMD ["/usr/local/bin/gunicorn", "-w", "2", "-b", ":8000", "manage:app"]
скопировать код
Здесь Гевин напрямую использует самый маленький образ Python-alpine в качестве базового образа, что значительно уменьшает размер создаваемого образа приложения Flask. Для alpine минималистичный образ всего с несколькими M, никакие другие системные зависимости не устанавливаются, напрямуюpip install uwsgi
сообщит об ошибке.
3.2 Конфигурация, связанная с Nginx
Nginx в основном выполняет обратный прокси-сервер и размещение статических файлов, что согласуется с приведенным выше файлом конфигурации, например:
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://blog:8000/;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /media {
alias /usr/share/nginx/html/media;
}
location /static {
alias /usr/share/nginx/html/static;
}
}
скопировать код
Единственная разница между этим файлом конфигурации и предыдущей главой заключается в том, что в строке 10proxy_pass http://blog:8000/;
Сервис обратного прокси здесьblog
, — это служба веб-сайта OctBlog, настроенная в Docker-compose ниже.
3.3 Оркестрация сервисов с помощью Docker-compose
Файл компоновки Docker для OctBlog выглядит следующим образом:
version: '3'
services:
blog:
# restart: always
image: gevin/octblog:0.4.1
volumes:
- blog-static:/usr/src/app/static
env_file: .env
networks:
- webnet
mongo:
# restart: always
image: mongo:3.2
volumes:
- /Users/gevin/projects/data/mongodb:/data/db
networks:
- webnet
blog-proxy:
# restart: always
image: nginx:stable-alpine
ports:
- "8080:80"
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
- blog-static:/usr/share/nginx/html/static:ro
- blog-static:/usr/share/nginx/html/media:ro
networks:
- webnet
volumes:
blog-static:
networks:
webnet:
скопировать код
Среди них, чтобы позволить нескольким службам взаимодействовать друг с другом, создается пользовательская сеть.webnet
, чтобы разрешить совместное использование файлов несколькими службами, томblog-static
.
4. Развертывание других веб-сайтов Python
Основываясь на вышеизложенном, мы также можем разобраться в общих процедурах различных веб-фреймворков Python для развертывания веб-сайта:
-
Разверните код с HTTP-сервером Python WSGI, например:
-
Green Unicorn
-
uWSGI
-
mod_wsgi
-
CherryPy
Обратный прокси с Nginx
Хорошо поработайте над размещением статических файлов
5. Примечание:
-
В дополнение к Nginx серверное программное обеспечение имеет другие варианты, такие как Apache.Гевин не имеет глубокого понимания другого серверного программного обеспечения для развертывания веб-сайтов Python, поэтому эта статья не охватывает его.
-
Исходный код OctBlog размещен на GitHub, вы можете выполнить поиск flyhigher139/OctBlog в этом репозитории, чтобы просмотреть
При написании этой статьи я ссылаюсь на следующее содержание, которое вы можете расширять и расширять:
Why flask + nginx + gunicorn:
-
What benefit is added by using Gunicorn + Nginx + Flask?
-
Why is setting Nginx as a reverse proxy a good idea?
-
What are the differences between nginx and gunicorn?
-
Why do I need Nginx and something like Gunicorn?
About Preforking:
-
The Preforking Model
Nginx serve flask static files:
-
How to serve Flask static files using Nginx?
-
nginx + uwsgi - what is serving static files?
Наконец,
Некоторое время назад в колонке «Geek Time» «Изучение архитектуры с 0», урок 18 «Режим высокой производительности с одним сервером: PPC и TPC» было более глубокое объяснение предварительного форка и связанных с ним знаний, я разместил плакат в конце статьи, если вы заинтересованы, отсканируйте QR-код на плакате, чтобы подписаться.Согласно текущим правилам маркетинга Geek Time, вы получите 8 юаней наличными.
6. What's More
Если не указано иное, статьи являются оригинальными от Gevin, и их перепечатка без разрешения Gevin запрещена.
Нажав «Прочитать исходный текст», вы откроете «блог Гевина», в котором удобнее читать код, и вы также сможете просмотреть соответствующие ссылки, упомянутые в статье.
Эта учетная запись одновременно публикует статьи в блоге, а также некоторый дополнительный технический контент для поверхностного чтения, приглашаю всех обратить внимание.