web服务器和web应用(框架)的关系梳理,兼谈nginx、wsgi、uWSGI、uwsgi、django。
WEB应用的访问流程
目前的web应用程序都是基于B(客户端-浏览器) / S(web服务器+web应用[框架])结构
#模拟一个客户端浏览器访问web服务器的过程
1.用户在浏览器中输入访问地址,也就是提供web应用服务的服务器地址。
a) 浏览器本质上是一个socket客户端程序;
b) 服务器本质上是一个随时等待客户端来访问连接的socket服务端程序,它会根据客户端的请求进行响应。
c) socket就是网络上应用程序之间进行通信的一套机制。
2.web服务器接到客户端的访问请求后,会转发给web应用程序[框架]对请求进行处理,web应用程序[框架]把处理结果返回,web服务器再返回给用户浏览器。
a) web服务器本质上是一个随时等待客户端来访问连接的socket服务端程序,它会根据客户端的请求进行响应。
b) 在python开发的web应用中,常用的web服务器包括Nginx+uWSGI(组合使用)
Nginx: 只是一个静态文件服务器或者http请求转发器,nginx实现了uwsgi协议, 通过uwsgi协议将请求转发给uWSGI,它实现了一部分web服务器功能。 Nginx擅长高并发,静态文件,Proxy,gzip压缩等等。 Nginx+uWSGI组合中,Nginx负责处理静态资源, 动态请求转给uWSGI调用Python来完成。 uWSGI: 是一个完整的Web服务器,它实现了WSGI协议、uwsgi、http等协议。如果使用Nginx+uWSGI组合,uWSGI就是实现了WSGI的一个中间件。
Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
nginx是不能直接部署python web的,因为nginx不支持WSGI规范。 当然nginx也可以实现,不过术业有专攻,nginx没有做。
uWSGI是实现了WSGI接口的,一个完整的http server,可以直接用来部署Python Web的,但为什么还需要Nginx呢?
因为Nginx擅长高并发,静态文件,gzip压缩等,这些功能是uWSGI不具备的。
如果你的网站访问量不大,可以只用uWSGI,完全不需要用Nginx。
所以现在流行的使用方法是Nginx+uWSGI (如下图),Nginx来完成Proxy,静态文件服务等,动态请求转给uWSGI调用Python来完成。
Nginx与uWSGI通过uwsgi(全部小写)协议来完成,uwsgi是一个二进制协议允许uWSGI与Nginx等应用服务器交互。
c) WSGI、uwsgi协议
WSGI(Web Server Gateway Interface):是Python应用程序或框架和Web服务器之间的一种接口,定义web server如何转发请求到Python写的应用中。
就像Java 的servlet API,这样只要实现接口的web server都可以调用遵守此接口的任何Python应用。
WSGI更像一个协议. 只要遵照这些协议,WSGI应用(Application)都可以在任何服务器(Server)上运行, 反之亦然。
WSGI是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Django、Flask框架写的程序)通信的一种规范。
WSGI 接口有服务端和应用端两部分,服务端也可以叫网关端,应用端也叫框架端 服务端调用一个由应用端提供的可调用对象。如何提供这个对象,由服务端决定。
例如某些服务器或者网关需要应用的部署者写一段脚本,以创建服务器或者网关的实例,并且为这个实例提供一个应用实例。
另一些服务器或者网关则可能使用配置文件或其他方法以指定应用实例应该从哪里导入或获取。
WSGI 对于 application 对象有如下三点要求: 必须是一个可调用的对象 接收两个必选参数environ、start_response。
返回值必须是可迭代对象,用来表示http body。
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框架,可以根据项目实际情况搭配使用。
uwsgi:uwsgi协议是uWSGI服务器单独使用的协议。
它是一个二进制协议,可以携带任何类型的数据。
一个uwsgi分组的头4个字节描述了这个分组包含的数据类型。
uwsgi通过将消息分片的方式,可以在一个socket上并发传输多个请求。
这样就在fastcgi减轻后端压力好处的基础上,解决了fastcgi一个连接上一次只能传输一个请求的问题。
熟悉HTTP2.0的话会发现这个分片机制跟HTTP2.0很像。
#不用Nginx,uWSGI也可以单独作为web服务器使用,流程如图。
总结:web服务器和web应用(框架)的关系
1.web 服务器 和 web 应用[框架],分工不同,职责不同(web 服务器专注于接收并解析请求以调用的方式将请求的内容传web框架),缺一不可,可以说它们是两个组件,共同协作才能实现web网页的访问。 2.web服务器端程序有Nginx+uWSGI的组合使用,如访问量少可单独使用uWSGI。 3.web应用(框架)有python开发的应用,或者使用python框架django、flask、Tornado等开发的应用。 4.用户浏览器,通过访问web服务器获取web应用(框架)提供的后台服务。下面用三个图反复描述他们之间的关系。
图一
图二
图三