WSGI-протокол
Сначала проясните следующие понятия:
WSGI:полное имяWeb Server Gateway Interface
,WSGI
не сервер,python
модули, фреймворки,API
или любое программное обеспечение, просто спецификация, описывающаяweb server
Как работать сweb application
Спецификации для связи.server
а такжеapplication
Спецификация находится вPEP 3333подробно описаны. Для реализации протокола WSGI должны быть реализованы как веб-сервер, так и веб-приложение, которые в настоящее время работают наWSGI
по соглашениюweb
кадр имеетBottle
, Flask
, Django
.
увсги:а такжеWSGI
Тот же протокол связи, даuWSGI
Эксклюзивный протокол сервера, определяющий тип передаваемой информации (type of information
),Каждыйuwsgi packet
вперед4byte
Для описания типа передаваемой информации это две вещи с протоколом WSGI.Говорят, что протоколfcgi
В 10 раз быстрее, чем протокол.
uWSGI:Являетсяweb
сервер, реализованныйWSGI
протокол,uwsgi
протокол,http
соглашение и др.
WSGI
Соглашение в основном включаетserver
а такжеapplication
Две части:
-
WSGI server
Ответственный за прием заявок от клиентов, будетrequest
вперед кapplication
,Будуapplication
вернутьresponse
возврат клиенту; -
WSGI application
полученоserver
перенаправленrequest
, обработать запрос и вернуть результат обработки вserver
.application
может включать промежуточное ПО с несколькими стеками (middlewares
), это ПО промежуточного слоя должно реализовывать как сервер, так и приложение, поэтому они могут играть роль посредника между сервером WSGI и приложением WSGI: для сервера ПО промежуточного слоя действует как приложение, а для приложения ПО промежуточного слоя действует как сервер .
WSGI
Протокол фактически определяетserver
а такжеapplication
Развязанная спецификация, т.е. может быть несколько реализацийWSGI server
сервер, также может быть несколько реализацийWSGI application
рамка, тогда вы можете выбрать любойserver
а такжеapplication
Комбинируя свои собственныеweb
заявление. НапримерuWSGI
а такжеGunicorn
это все реализованоWSGI server
сервер протоколов,Django
,Flask
реализуетсяWSGI application
протоколweb
Фреймворк можно использовать в сочетании с реальной ситуацией проекта.
картинаDjango
,Flask
Фреймворк имеет собственную реализацию простогоWSGI server
, обычно используемый для отладки сервера, рекомендуется использовать другиеWSGI server
.
Реализация протокола WSGI
кDjango
Например, проанализируемWSGI
Конкретный процесс реализации протокола.
django WSGI application
WSGI application
Должен быть реализован как вызываемый объект, такой как функция, метод, класс (содержащий `call`метод). Нужно получить два параметра:
- Словарь, который может содержать информацию и другую информацию, запрошенную клиентом, может считаться контекстом запроса, обычно называемым
environment
(В кодировании это часто сокращается какenviron
,env
) - Один для отправки статуса ответа HTTP (
HTTP status
), заголовки ответов (HTTP headers
) функция обратного вызова
Верните статус ответа и заголовки ответа через функцию обратного вызова вserver
при возврате тела ответ (response body
), тело ответа повторяемо и содержит несколько строк. НижеDjango
серединаapplication
Конкретная часть реализации:
class WSGIHandler(base.BaseHandler):
initLock = Lock()
request_class = WSGIRequest
def __call__(self, environ, start_response):
# 加载中间件
if self._request_middleware is None:
with self.initLock:
try:
# Check that middleware is still uninitialized.
if self._request_middleware is None:
self.load_middleware()
except:
# Unload whatever middleware we got
self._request_middleware = None
raise
set_script_prefix(get_script_name(environ))
# 请求处理之前发送信号
signals.request_started.send(sender=self.__class__, environ=environ)
try:
request = self.request_class(environ)
except UnicodeDecodeError:
logger.warning('Bad Request (UnicodeDecodeError)',
exc_info=sys.exc_info(),
extra={'status_code': 400,})
response = http.HttpResponseBadRequest()
else:
response = self.get_response(request)
response._handler_class = self.__class__
status = '%s %s' % (response.status_code, response.reason_phrase)
response_headers = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
# server提供的回调方法,将响应的header和status返回给server
start_response(force_str(status), response_headers)
if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'):
response = environ['wsgi.file_wrapper'](response.file_to_stream)
return response
Как можно заметитьapplication
Процесс включает в себя:
- Загрузите все промежуточное программное обеспечение, выполните операции, связанные с Framework, установите префикс скрипта текущего потока и отправьте сигнал запуска запроса;
- обработать заявку, позвонить
get_response()
Метод обрабатывает текущий запрос, и основная логика этого метода заключается в следующем:urlconf
найти соответствующийview
а такжеcallback
, выполнять различныеmiddleware
а такжеcallback
. - вызванный
server
входящийstart_response()
метод ответитheader
а такжеstatus
Вернуться кserver
. - вернуть тело ответа
django WSGI Server
ответственный за получениеhttp
запрос, передать запросWSGI application
,Зависит отapplication
возврат после обработки запросаresponse
. кDjango
встроенныйserver
Взгляните на конкретную реализацию в качестве примера.
пройти черезrunserver
бегатьdjango
Project, вызовет в начале следующегоrun
метод, создайтеWSGIServer
экземпляр , а затем вызовите егоserve_forever()
способ запуска службы.
def run(addr, port, wsgi_handler, ipv6=False, threading=False):
server_address = (addr, port)
if threading:
httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {})
else:
httpd_cls = WSGIServer
# 这里的wsgi_handler就是WSGIApplication
httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)
if threading:
httpd.daemon_threads = True
httpd.set_app(wsgi_handler)
httpd.serve_forever()
Следующее указываетWSGI server
Ключевые классы и методы в потоке обработки сервера.
- WSGIServer
run()
Метод создаетWSGIServer
Примеры, основная роль — получение клиентских запросов, передача запроса вapplication
,Потомapplication
вернутьresponse
возвращен клиенту.- При создании экземпляра указывается
HTTP
просилhandler
:WSGIRequestHandler
Добрый - пройти через
set_app
а такжеget_app
Установить метод и получитьWSGIApplication
примерwsgi_handler
- При обработке http-запроса вызовите
handler_request
метод, создастWSGIRequestHandler
Экземпляр обрабатывает http-запросы. -
WSGIServer
серединаget_request
метод переданsocket
принять данные запроса
- При создании экземпляра указывается
- WSGIRequestHandler
- Зависит от
WSGIServer
вызовhandle_request
При создании экземпляра передатьrequest
,cient_address
,WSGIServer
три параметра,__init__
Когда метод создается, он также вызывает свой собственныйhandle
метод -
handle
метод создастServerHandler
экземпляр, а затем вызвать егоrun
способ обработки запроса
- Зависит от
- ServerHandler
-
WSGIRequestHandler
В своемhandle
вызов методаrun
метод, пройтиself.server.get_app()
параметры, получитьWSGIApplication
, а затем вызовите экземпляр (__call__
),Получатьresponse
, который пройдет вstart_response
обратный вызов, используемый для обработки возвращенногоheader
а такжеstatus
. - пройти через
application
Получатьresponse
позже, черезfinish_response
вернутьresponse
-
- WSGIHandler
-
WSGI
в соглашенииapplication
, получает два параметра,environ
Словарь содержит информацию и другую информацию, запрошенную клиентом, ее можно считать контекстом запроса,start_response
для отправки обратноstatus
а такжеheader
функция обратного вызова
-
Хотя тот, что вышеWSGI server
Он включает несколько реализаций классов и взаимные ссылки, но на самом деле принцип заключается в вызовеWSGIHandler
, параметры входящего запроса и метод обратного вызоваstart_response()
и вернуть ответ клиенту.
django simple_server
django
изsimple_server.py
Модуль реализует простуюHTTP
сервер и дает простойdemo
, вы можете запустить его напрямую, и результат выполнения отобразит переменные среды, задействованные в запросе, в браузере.
который включает в себя всюhttp
Все компоненты запроса:
ServerHandler
, WSGIServer
, WSGIRequestHandler
,так же какdemo_app
упрощенный вариант представленияWSGIApplication
.
Вы можете посмотреть на весь процесс:
if __name__ == '__main__':
# 通过make_server方法创建WSGIServer实例
# 传入建议application,demo_app
httpd = make_server('', 8000, demo_app)
sa = httpd.socket.getsockname()
print("Serving HTTP on", sa[0], "port", sa[1], "...")
import webbrowser
webbrowser.open('http://localhost:8000/xyz?abc')
# 调用WSGIServer的handle_request方法处理http请求
httpd.handle_request() # serve one request, then exit
httpd.server_close()
def make_server(
host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
):
"""Create a new WSGI server listening on `host` and `port` for `app`"""
server = server_class((host, port), handler_class)
server.set_app(app)
return server
# demo_app可调用对象,接受请求输出结果
def demo_app(environ,start_response):
from io import StringIO
stdout = StringIO()
print("Hello world!", file=stdout)
print(file=stdout)
h = sorted(environ.items())
for k,v in h:
print(k,'=',repr(v), file=stdout)
start_response("200 OK", [('Content-Type','text/plain; charset=utf-8')])
return [stdout.getvalue().encode("utf-8")]
demo_app()
Представляет простую реализацию приложения WSGI черезmake_server()
метод созданияWSGIServer
экземпляр, назовите егоhandle_request()
метод, который вызываетdemo_app()
Обработайте запрос и, наконец, верните ответ.
uWSGI
uWSGI
Он направлен на разработку комплексного решения для развертывания сетевых приложений в распределенных кластерах. В основном дляweb
и его стандартные услуги. Благодаря своей расширяемости его можно расширить для поддержки большего количества платформ и языков без ограничений.uWSGI
Являетсяweb
сервер, реализованныйWSGI
протокол,uwsgi
протокол,http
соглашение и др.
uWSGI
Основные особенности:
- супер быстрая производительность
- Низкий объем памяти
- много
app
управлять - Функция подробного журнала (можно использовать для анализа
app
производительность и узкие места) - Широкие возможности настройки (ограничение объема памяти, перезапуск службы после определенного количества раз и т. д.)
uWSGI
Сервер реализует свои собственные на основеuwsgi
протоколserver
раздел, нам просто нужноuwsgi
указывается в конфигурационном файлеapplication
адрес,uWSGI
непосредственно и фреймворк приложенияWSGI application
коммуникация.
эталонное чтение:
WSGI & uwsgi
WSGI Tutorial
Преимущества, недостатки и реализация интерфейса протокола wsgi для построения фреймворка mvc
Механизм связи Nginx и uWSGI
Понимание Python WSGI