当咱们部署完一个应用程序,浏览网页时具体的过程是怎样的呢?首先咱们得有一个 Web 服务器来处理 HTTP 协议的内容,Web 服务器得到客户端的请求,交给应用程序,应用程序处理完,返回给 Web 服务器,这时 Web 服务器再返回给客户端。Web 服务器与应用程序之间显然要进行交互,这时就出现了不少 Web 服务器与应用程序之间交互的规范,最先出现的是 CGI,后来又出现了改进 CGI 性能的FasgCGI,Java 专用的 Servlet 规范,Python 专用的 WSGI 规范等等。有了统一标准,程序的可移植性就大大提升了。这里咱们只介绍 WSGI。html

WSGI 全称是 Web Server Gateway Interface,也就是 Web 服务器网关接口,它是 Python 语言定义出来的 Web 服务器和 Web 应用程序之间的简单而通用的接口,基于现存的 CGI 标准设计,后来在不少其余语言中也出现了相似的接口。 总的来讲,WSGI 能够分为服务器和应用程序两个部分,实际上能够将 WSGI 理解为服务器与应用程序之间的一座桥,桥的一边是服务器,另外一边是应用程序。python

按照 web 组件分类,WSGI 内部能够分为三类,web 应用程序,web 服务器,web 中间件。应用程序端的部分经过Python 语言的各类 Web 框架实现,好比 Flask,Django这些,有了框架,开发者就不须要处理 WSGI,框架会帮忙解决这些,开发者只需处理 HTTP 请求和响应,web 服务器的部分就要复杂一点,能够经过 uWSGI 实现,也能够用最多见的 Web 服务器,好比 Apache、Nginx,但这些 Web 服务器没有内置 WSGI 的实现,是经过扩展完成的。如 Apache,经过扩展模块 mod_wsgi 来支持WSGI,Nginx能够经过代理的方式,将请求封装好,交给应用服务器,好比 uWSGI。uWSGI 能够完成 WSGI 的服务端,进程管理以及对应用的调用。WSGI 中间件的部分能够这样理解:咱们把 WSGI 看作桥,这个桥有两个桥墩,一个是应用程序端,另外一个是服务器端,那么桥面就是 WSGI 中间件,中间件同时具有服务器、应用程序端两个角色,固然也须要同时遵照 WSGI 服务器和 WSGI 应用程序两边的限制和须要。更详细的内容能够看PEP-333 中间件的描述web

Flask 依赖的 Werkzeug 就是一个 WSGI 工具包,官方文档的定义是 Werkzeug 是为 Python 设计的 HTTP和 WSGI 实用程序库。咱们须要注意的是,Flask 自带的 Werkzeug 是用来开发的,并不能用于生产环境,Flask 是 Web 框架,而 Werkzeug 不是 Web框架,不是 Web 服务器,它只是一个 WSGI 工具包,它在 Flask 的做用是做为 Web 框架的底层库,它方便了咱们的开发。django

咱们将 uwsgi 和 uWSGI 放在一块儿讲解。uWSGI 是一个 Web 服务器程序,WSGI,上面已经谈到,是一种协议,uwsgi 也是一种协议,uWSGI 实现了 uwsgi、WSGI、http 等协议。 uwsgi 的介绍能够看这里,uwsgi 是 uWSGI 使用的一个自有的协议,它用4个字节来定义传输数据类型描述。尽管都是协议,uwsgi 和 WSGI 并无联系,咱们须要区分这两个词。flask

Nginx

Nginx 是高效的 Web 服务器和反向代理服务器,能够用做负载均衡(当有 n 个用户访问服务器时,能够实现分流,分担服务器的压力),与 Apache 相比,Nginx 支持高并发,能够支持百万级的 TCP 链接,十万级别的并发链接,部署简单,内存消耗少,成本低,但 Nginx 的模块没有 Apache 丰富。Nginx 支持 uWSGI 的 uwsgi 协议,所以咱们能够将 Nginx 与 uWSGI 结合起来,Nginx 经过 uwsgi_pass 将动态内容交给 uWSGI 处理。缓存

uWSGI 和 Nginx 的关系

从上面的讲解中,咱们知道,uWSGI 能够起到 Web 服务器的做用,那么为何有了 uWSGI 还须要 Nginx 呢?安全

最广泛的说法是 Nginx 对于处理静态文件更有优点,性能更好。其实若是是小网站,没有静态文件须要处理,只用 uWSGI 也是能够的,但加上 Nginx 这一层,优点能够很具体:服务器

  1. 对于运维来讲比较方便,若是服务器被某个 IP 攻击,在 Nginx 配置文件黑名单中添加这个 IP 便可,若是只用 uWSGI,那么就须要在代码中修改了。另外一方面,Nginx 是身经百战的 Web 服务器了,在表现上 uWSGI 显得更专业,好比说 uWSGI 在早期版本里是不支持 https 的,能够说 Nginx 更安全。
  2. Nginx 的特色是可以作负载均衡和 HTTP 缓存,若是不止一台服务器,Nginx 基本就是必选项了,经过 Nginx,将资源能够分配给不一样的服务器节点,只有一台服务器,也能很好地提升性能,由于 Nginx 能够经过 headers 的Expires or E-Tag,gzip 压缩等方式很好地处理静态资源,毕竟是 C 语言写的,调用的是 native 的函数,针对 I/O作了优化,对于动态资源来讲,Nginx 还能够实现缓存的功能,配合 CDN 优化(这是 uWSGI 作不到的)。Nginx 支持epoll/kqueue 等高效网络库,可以很好地处理高并发短链接请求,性能比 uWSGI 不知道高到哪里去了。
  3. 若是服务器主机上运行了PHP,Python 等语言写的多个应用,都须要监听80端口,这时候 Nginx 就是必选项了。由于咱们须要一个转发的服务。
WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web server如何与web application通讯的规范。要实现WSGI协议,必须同时实现web server和web application,当前运行在WSGI协议之上的web框架有Bottle, Flask, Django。
uwsgi:与WSGI同样是一种通讯协议,是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information)
uWSGI:是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等。
WSGI协议主要包括server和application两部分:
WSGI server负责从客户端接收请求,将request转发给application,将application返回的response返回给客户端;
WSGI application接收由server转发的request,处理请求,并将处理结果返回给server。application中能够包括多个栈式的中间件(middlewares),这些中间件须要同时实现server与application,所以能够在WSGI服务器与WSGI应用之间起调节做用:对服务器来讲,中间件扮演应用程序,对应用程序来讲,中间件扮演服务器。
WSGI协议实际上是定义了一种server与application解耦的规范,便可以有多个实现WSGI server的服务器,也能够有多个实现WSGI application的框架,那么就能够选择任意的server和application组合实现本身的web应用。例如uWSGI和Gunicorn都是实现了WSGI server协议的服务器,Django,Flask是实现了WSGI application协议的web框架,能够根据项目实际状况搭配使用。

 

 

Nginx+uWSGI+应用程序的架构

image