Как веб-фреймворки Python, WSGI и CGI подходят друг другу


150

У меня есть учетная запись Bluehost, где я могу запускать скрипты Python как CGI. Я думаю, это самый простой CGI, потому что для запуска мне нужно определить следующее в .htaccess:

Options +ExecCGI
AddType text/html py
AddHandler cgi-script .py

Теперь, когда я смотрю веб-программирование на Python, я много слышу о WSGI и о том, как его использует большинство фреймворков. Но я просто не понимаю, как все это сочетается, особенно когда мой веб-сервер (Apache работает на компьютере хоста), а не то, с чем я действительно могу играть (кроме определения .htaccessкоманд).

Как связаны между собой WSGI , CGI и фреймворки? Что мне нужно знать, устанавливать и делать, если я хочу запустить веб-фреймворк (скажем, web.py или CherryPy ) в моей базовой конфигурации CGI? Как установить поддержку WSGI?

Ответы:


242

Как WSGI, CGI и фреймворки связаны между собой?

Apache прослушивает порт 80. Получает HTTP-запрос. Он анализирует запрос, чтобы найти способ ответить. Апач имеет много вариантов ответа. Один из способов ответа - использовать CGI для запуска скрипта. Другой способ ответить - просто подать файл.

В случае CGI Apache подготавливает среду и вызывает сценарий по протоколу CGI. Это стандартная ситуация Unix Fork / Exec - подпроцесс CGI наследует среду ОС, включая сокет и стандартный вывод. Подпроцесс CGI записывает ответ, который возвращается к Apache; Apache отправляет этот ответ в браузер.

CGI примитивен и раздражает. Главным образом потому, что он разветвляет подпроцесс для каждого запроса, а подпроцесс должен закрыть или закрыть stdout и stderr, чтобы обозначить конец ответа.

WSGI - это интерфейс, основанный на шаблоне проектирования CGI. Это не обязательно CGI - он не должен обрабатывать подпроцесс для каждого запроса. Это может быть CGI, но это не обязательно.

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

Что мне нужно знать / установить / сделать, если я хочу запустить веб-фреймворк (скажем, web.py или cherrypy) в моей базовой конфигурации CGI?

Напомним, что разветвление подпроцесса стоит дорого. Есть два способа обойти это.

  1. Встраивает mod_wsgi или mod_pythonвстраивает Python в Apache; ни один процесс не разветвлен. Apache запускает приложение Django напрямую.

  2. Демон mod_wsgi или mod_fastcgiпозволяет Apache взаимодействовать с отдельным демоном (или «длительным процессом»), используя протокол WSGI. Вы запускаете длительный процесс Django, а затем настраиваете Apache mod_fastcgi для связи с этим процессом.

Обратите внимание, что mod_wsgiможет работать в любом режиме: встроенный или демон.

Когда вы прочитаете о mod_fastcgi, вы увидите, что Django использует flup для создания WSGI-совместимого интерфейса на основе информации, предоставленной mod_fastcgi. Трубопровод работает так.

Apache -> mod_fastcgi -> FLUP (via FastCGI protocol) -> Django (via WSGI protocol)

У Django есть несколько «django.core.handlers» для различных интерфейсов.

Для mod_fastcgi Django предоставляет объект, manage.py runfcgiкоторый интегрирует FLUP и обработчик.

Для mod_wsgi для этого есть основной обработчик.

Как установить поддержку WSGI?

Следуйте этим инструкциям.

https://code.google.com/archive/p/modwsgi/wikis/IntegrationWithDjango.wiki

Для фона см. Это

http://docs.djangoproject.com/en/dev/howto/deployment/#howto-deployment-index


4
Я не могу установить mod_wsgi, потому что я на виртуальном хостинге. Все, что у меня есть, это поддержка fcgi. Как я могу по-прежнему запускать приложения WSGI через него?
— Эли Бендерский

3
+1 Это отличный ответ и ответы на многие (но не все) вопросы, которые я имею в виду. Этот ответ еще не завершен. Вы хорошо объяснили о CGI и WSGI, но какова связь и различия между FASTCGI и WSGI? Что лучше? Как они работают? Как mod_python попал в картину?
— когти

14
S.Lott вместо того, чтобы жаловаться на то, что когда люди спрашивают, что «лучше», почему бы просто не заявить, что «mod_wsgi лучше как X, fastcgi лучше для Y», и если у ОП есть более конкретные вопросы, они будут задавать.
— Грегг Линд

7
@ Грег Линд: Почему бы просто не заявить, что "mod_wsgi лучше как X, fastcgi лучше для Y"? Потому что это не очень легко сделать. Существуют десятки нефункциональных факторов качества, которые являются элементами наборов X и Y. Трудно перечислить их все. Для людей гораздо лучше задавать конкретные вопросы о факторах качества, которые имеют отношение к делу.
— S.Lott

4
Только для заметок: опция runfcgi устарела с версии 1.7, а поддержка FastCGI была удалена в Django 1.9.
— OBu

58

Я думаю, что ответ Флориана отвечает на ваш вопрос о том, что такое WSGI, особенно если вы читаете PEP .

Что касается вопросов, которые вы ставите ближе к концу:

WSGI, CGI, FastCGI и т. Д. - все это протоколы для веб-сервера для запуска кода и доставки динамического контента, который создается. Сравните это со статической веб-службой, где обычный HTML-файл в основном доставляется клиенту.

CGI, FastCGI и SCGI не зависят от языка. Вы можете писать CGI-скрипты на Perl, Python, C, Bash, что угодно. CGI определяет , который исполняемый файл будет называться, на основе URL, и как она будет называться: аргументы и окружающей среды. Он также определяет, как возвращаемое значение должно быть передано обратно на веб-сервер после завершения вашего исполняемого файла. Варианты - это в основном оптимизация, позволяющая обрабатывать больше запросов, снижать задержку и т. Д .; основная концепция та же самая.

WSGI - это только Python. Вместо протокола, независимого от языка, определяется стандартная сигнатура функции:

def simple_app(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['Hello world!\n']

Это полное (если ограниченное) приложение WSGI. Веб-сервер с поддержкой WSGI (например, Apache с mod_wsgi) может вызывать эту функцию всякий раз, когда поступает запрос.

Причина, по которой это так здорово, заключается в том, что мы можем избежать грязного шага преобразования HTTP GET / POST в CGI в Python и обратно на выход. Это гораздо более прямая, чистая и эффективная связь.

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

Чтобы иметь поддержку WSGI, вам необходимо установить модуль WSGI (например, mod_wsgi ) или использовать веб-сервер с встроенным WSGI (например, CherryPy ). Если ни то, ни другое невозможно, вы можете использовать мост CGI-WSGI, указанный в PEP.


3
Чья это глупая идея - не делать язык WSGI независимым? Какой смысл тогда? Можно также отправить весь Python как модуль Apache.
— Салман фон Аббас

2
@ SalmanPK Я думаю, что это просто компромисс. Конечно, нелегко (если не невозможно) создать независимый от языка протокол, который можно использовать, просто реализуя функцию на выбранном языке.
— phunehehe

21

Вы можете запустить WSGI через CGI, как показано в примере Pep333 . Однако каждый раз, когда появляется запрос, запускается новый интерпретатор Python, и необходимо создавать весь контекст (соединения с базой данных и т. Д.), Что занимает много времени.

Лучше всего, если вы захотите запустить WSGI, если бы ваш хост установил mod_wsgi и выполнил соответствующую конфигурацию, чтобы перенести управление на ваше приложение.

Flup - это еще один способ работы с WSGI для любого веб-сервера, который может говорить на FCGI , SCGI или AJP. Из моего опыта действительно работает только FCGI, и он может быть использован в Apache либо через mod_fastcgi, либо если вы можете запустить отдельный демон Python с mod_proxy_fcgi .

WSGI - это протокол, очень похожий на CGI, который определяет набор правил взаимодействия веб-сервера и кода Python, он определяется как Pep333 . Это позволяет многим различным веб-серверам использовать множество различных сред и приложений, использующих один и тот же протокол приложения. Это очень полезно и делает его таким полезным.


3
Работает ли WSGI поверх CGI, для чего нужен «flup»? Как flup связан со схемой?
— Эли Бендерский

7

Если вам неясны все термины в этом пространстве, и давайте посмотрим правде в глаза, это сбивает с толку запутанный акроним, есть также хороший фоновый читатель в форме официального HOWTO на питоне, в котором обсуждаются CGI против FastCGI против WSGI и так далее. на: http://docs.python.org/howto/webservers.html


2
URL устарел, я думаю, что он обновлен: docs.python.org/2.7/howto/webservers.html
— Stefaan

Отличный материал :) Необходимо прочитать это официальное введение вместе с принятым ответом.
— Рик

4

Это простой уровень абстракции для Python, похожий на спецификацию Servlet для Java. В то время как CGI действительно низкоуровневый и просто сбрасывает данные в среду процесса и стандартный ввод / вывод, две вышеупомянутые спецификации моделируют запрос и ответ http как конструкции на языке. Однако у меня сложилось впечатление, что в Python люди не совсем остановились на фактических реализациях, поэтому у вас есть набор эталонных реализаций и другие библиотеки типов утилит, которые предоставляют другие функции наряду с поддержкой WSGI (например, Paste). Конечно, я могу ошибаться, я новичок в Python. Сообщество "веб-сценариев" сталкивается с проблемой в другом направлении (виртуальный хостинг, наследие CGI,

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.