Nginx+uWSGI+Django原理(转发)

Python的Web开发中,若是使用Django框架,那么较为成熟稳定的服务器架构通常是Nginx+uWSGI+Django。而为何必定要三个结合在一块儿呢?直接使用Django的runserver来启动服务器进程,或者uWSGI+Django可不能够呢?为何? 
概念说明:html

  • APP(应用程序),就是开发者写的应用程序,例如django,bottle这些。记录怎么处理客户端发来的请求的逻辑部分。
  • WSGI,是一个协议,Python用于Web开发的协议
  • uWSGI,是一个程序,充当Web服务器或中间件。
    • 若是架构是Nginx+uWSGI+APP,uWSGI是一个中间件
    • 若是架构是uWSGI+APP,uWSGI是一个服务器
  • uwsgi,是uWSGI程序实现的一个自有的协议。

Web协议出现顺序: 
CGI -> FCGI -> WSGI -> uwsgipython

  1. CGI,最先的协议
  2. FCGI,比CGI快
  3. WSGI,Python专用的协议
  4. uwsgi,比FCGI和WSGI都快,是uWSGI项目自有的协议,主要特征是采用二进制来存储数据,以前的协议都是使用字符串,因此在存储空间和解析速度上,都优于字符串型协议.官方介绍

1、WSGI协议

浏览器请求一个页面的流程:git

  1. 浏览器发送请求给服务器,包含请求头和请求体
  2. 服务器解析请求头和请求体
  3. 服务器根据请求信息来处理请求,生成返回内容
  4. 服务器生成响应头和响应体
  5. 服务器返回响应给浏览器,浏览器显示给用户

一个网站,通常有不少个不一样的请求,在这些请求中,基本1,2,4,5部都是固定的,变的只有第三步,因此把这四步抽象出来,让开发者只关注第三步,这样就能够极大提高开发效率。因此WSGI协议诞生了。 
WSGI,全称 Web Server Gateway Interface。是Python专用的协议,其余语言没有。用于处理Web服务器和应用程序(APP)的交互信息。不少Web框架(如:django)都会自带WSGI服务器,可是性能很差,只做测试用途。github

实现一个最简单的服务器web

  1. app.py
  1. import pprint
  2. def application(environ, start_response):
  3. pprint.pprint(environ)
  4. start_response('200 OK',[('Content-Type','text/html')])
  5. return'<h1>Hello, web!</h1>'
  • environ参数是一个字典对象,保存HTTP请求的信息。例如URL路径,域名,请求头,请求参数等
  • start_response参数是一个函数,用于向wsgiref提供响应头的设置,只能调用一次。
  1. server.py
  1. # 从wsgiref模块导入:
  2. from wsgiref.simple_server import make_server
  3. # 导入咱们本身编写的application函数:
  4. from app import application
  5. # 建立一个服务器,IP地址为空,端口是8000,处理函数是application:
  6. httpd = make_server('',8000, application)
  7. print"Serving HTTP on port 8000..."
  8. # 开始监听HTTP请求:
  9. httpd.serve_forever()
  1. 启动python server.py,就能够经过localhost:8000访问了

wsgiref模块是python提供的,用于测试和学习的简单的WSGI服务器模块。 
这个模块监听8000端口,把Http请求,根据WSGI协议,转换application函数中的environ参数,而后调用application函数。 
wsgiref会把application函数提供的响应头设置转换为HTTP协议的响应头,把application的返回(return)做为响应体,根据HTTP协议,生成响应,返回给浏览器。django

Alt text

这样,应用程序就不须要关注底层的HTTP协议细则了浏览器

2、CGI和FastCGI

CGI是Common Gateway Interface,即通用网关接口,是一个协议,是外部应用程序(CGI程序)与Web服务器之间的接口标准。该协议定义了Web服务器在调用应用程序时须要传输的参数和应用程序怎么返回结果给Web服务器,其实跟WSGI相似。 
CGI的一个特色是,对于每个HTTP请求,Web服务器都会新建一个进程(fork),等应用程序返回结果后,这个进程就会结束。这样的后果是,一旦HTTP请求多的时候,Web服务器会频繁建立进程,你们都知道,建立进程的开销是很是大的,因此这种作法会影响服务器的性能,因此就有了FastCGI。 
FCGI的作法是在Web服务器启动的时候,就建立多个应用程序进程,当Web服务器接收到HTTP请求时,就把请求分发给其中一个空闲的进程。至关于MYSQL链接池的原理。这样就能够避免频繁地fork进程。FCGI另外一个特色是支持分布式,也就是Web服务器和应用程序能够在不一样的机器。 
CGI和WSGI的区别是安全

  • CGI的出现更加早,这个是通用的接口,应用程序能够是JAVA,Python,等多种语言程序
  • WSGI是Python专用的,在CGI的基础上改进的协议

3、Nginx

Ningx是一个反向代理服务器 
什么是反向代理?服务器

  1. 正向代理,例如FQ用的代理服务器就是正向代理,浏览器主动请求代理服务器,代理服务器转发请求到对应的目标服务器
  2. 反向代理,部署在Web服务器上,代理全部外部网络对内部网络的访问。浏览器访问服务器,必须通过这个代理,是被动的。 
    正向代理的主动方是客户端,反向代理的主动方是Web服务器。 
    结构图: 
    Alt text

反向代理的做用:网络

  1. 安全,客户端对Web服务器的访问须要先通过反向代理服务器。这样能够防止外部程序对Web服务器的直接攻击。
  2. 负载均衡,反向代理服务器能够根据Web服务器的负载状况,动态地把HTTP请求交给不一样的Web服务器来处理,前提是要有多个Web服务器。
  3. 提高Web服务器的IO性能。一个HTTP请求的数据,从客户端传输给服务器,是须要时间的,例如N秒,若是直接传给Web服务器,Web服务器就须要让一个进程阻塞N秒,来接收IO,这样会下降Web服务器的性能。若是使用反向代理服务器,先让反向代理服务器接收完整个HTTP请求,再把请求发给Web服务器,就能提高Web服务器的性能。还有一些静态文件的请求,能够直接交给反向代理来处理,不须要通过Web服务器。

Nginx是一个高性能的HTTP和反向代理服务器。

Nginx+uWSGI+应用程序的架构: 
Alt text

其中Nginx和uWSGI之间能够经过CGI,FCGI和uwsgi协议通讯,固然uwsgi的性能是最好的。

4、总结

  1. uWSGI+Django比单独使用Django的好处:
    • 支持的并发量更高
    • 方便管理多进程,发挥多核的优点
    • 提高性能,由于uwsgi协议比WSGI协议有优点
  2. Nginx+uWSGI+Django比uWSGI+Django好处(参考反向代理的做用):

最后附上一个介绍Nginx+uWSGI+Django的幻灯片

参考: 
http://www.biaodianfu.com/cgi-fastcgi-wsgi.html 
http://blog.csdn.net/qiaofeiw/article/details/9207359 
http://www.cnblogs.com/wanghetao/p/3934350.html 
http://book.51cto.com/art/201202/314840.htm 
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832689740b04430a98f614b6da89da2157ea3efe2000 
https://www.douban.com/note/13508388/ 
http://www.nowamagic.net/academy/detail/1330308 
http://www.itopers.com:8080/?p=586

相关文章
相关标签/搜索