引言
经常在各种项目部署的教程中看到,要将Django部署在uWSGI服务器上,将FastAPI部署在Uvicorn服务器上,为什么要这样做?首先我们要了解什么是WSGI。
什么是WSGI?
WSGI不是服务器、python模块、web框架、API或者任何软件。WSGI是一个协议,用来定义web服务器和python web应用之间的交互。如果一个web应用实现了WSGI协议,那么这个应用就可以在各种实现了WSGI的服务器中使用。简单来说请求先进到WSGI服务器中,WSGI服务器按照协议把收到的信息处理为python对象,然后把python对象交给应用处理。
举个常见的例子:uWSGI的是由C/C++编写的实现了WSGI的服务器,它具有很棒的性能,而Django则是实现了WSGI的Web应用。当客户端向我们发来请求时,uWSGI负责建立连接并接收数据,然后将数据转化为python程序可以处理的dict,再转交给Django处理;Django收到数据后根据路由业务等代码再进行处理,最后要向uWSGI返回一个结果,再由uWSGI把结果返回给客户端。正因为WSGI协议的存在,才使得Django和uWSGI之间的交流畅通无阻。
因为WSGI的存在,使得满足协议的python应用可以在各种服务器中使用。服务器专注以高性能的网络连接,而web应用则专注于处理路由和业务等。
什么是ASGI?
ASGI是WSGI的继承制,目的在于给具有异步功能的python web服务器、框架和应用程序之间提供标准的接口。WSGI仅支持同步,而ASGI支持同步和异步。UVicorn就是一个实现了ASGI的web服务器,Fast API’是一个实现了ASGI的web框架,道理是相同的,不过多赘述。
在代码中体会
文章的最后我们使用wsgiref库来模拟一个python应用,帮助我们体会其中的过程。
wsgiref是python标准库的一部分直接导入就行,它是实现WSGI了的参考服务器。
你可以运行它,访问http://localhost:8000/,感受一下WSGI服务器和web应用的交互过程。
from wsgiref.simple_server import make_server
def app(environ, start_response):
# print(type(environ))
# print(environ)
status = "200 OK"
headers = [("Content-type", "text/plain")]
start_response(status, headers)
return [b"Hello World"]
with make_server("", 8000, app) as httpd:
print("Listening on port 8000....")
httpd.serve_forever()