本篇文章推荐个好东西,它就是 granian,不过在介绍之前,需要先补充一些背景知识。在学习 Python Web 开发时,我们肯定会接触到以下几个概念。
那么它们之间有什么区别呢?这里总结一下。
WSGI
WSGI 的全称是 Web Server Gateway Interface(Web 服务器网关接口),是一种描述Web 服务器和Web 应用程序(使用 Web 框架,如 Django、Flask 编写的程序)进行通信的规范、协议。
由于任何一个框架编写的服务都必须运行在 Web 服务器上,所以这两者必须遵循相同的通信规范,而这个规范就是 WSGI。实现了 WSGI 协议的框架,我们称之为 WSGI 框架,实现了 WSGI 协议的服务器,我们称之为 WSGI 服务器。
uWSGI
一个实现了 WSGI 协议的 Web 服务器,将使用 Web 框架编写好的应用部署在 uWSGI 服务器上是可以直接对外提供服务的。当然 WSGI 服务器除了 uWSGI 之外,还有 Gunicorn 等等,它们不仅实现了 WSGI 协议,还实现了 uwsgi 协议和 HTTP 协议。
Nginx
同样是一个 Web 服务器,但它相比 uWSGI 可以提供更多的功能,比如反向代理、负载均衡、缓存静态资源、对 HTTP 请求更加友好,这些都是 uWSGI 所不具备或者不擅长的。
所以我们将 Web 服务部署在 uWSGI 之后,还要在前面再搭一层 Nginx。此时 uWSGI 就不再暴露 HTTP 服务了,而是暴露 TCP 服务,因为它是和 Nginx 进行通信,使用 TCP 会更快一些,Nginx 来对外暴露 HTTP 服务。
uwsgi
Nginx 和 uWSGI 通信所采用的协议,因为 uWSGI 是和 Nginx 对接,所以这两者也要遵循相同的协议,这个协议就是 uwsgi。对于一个 HTTP 请求,Nginx 在收到之后,会进行判断。
- 如果请求的是静态资源,那么 Nginx 直接就处理了;
- 如果请求的是动态资源,那么会将请求转发给 uWSGI,然后再由 uWSGI 调用相应的 Web 服务进行处理,处理完毕之后将结果交给 Nginx,Nginx 再返回给客户端。
Nginx 内部有一个 HttpUwsgiModule 模块,它的作用就是让 Nginx 具备和 uWSGI 通信的功能。
在 WSGI 之前,选择一个框架可能会限制 Web 服务器的可用接口的种类,因为两者之间没有标准化的接口,而 WSGI 则通过提供一个简单的 API 解决了这个问题。2004 年,随着 PEP-333 的出现,现已成为 Web 应用程序部署的实际标准。
我们来构建一个最简单的 WSGI 应用程序。
# main.py
def application(env, start_response):
print(env)
start_response("200 OK", [("Content-Type", "text/html")])
return [b"WSGI hello!"]