Python的Web开发中,如果使用Django框架,那么较为成熟稳定的服务器架构一般是Nginx+uWSGI+Django。而为什么一定要三个结合在一起呢?直接使用Django的runserver来启动服务器进程,或者uWSGI+Django可不可以呢?为什么? 
概念说明:

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

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

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

一、WSGI协议

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

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

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

实现一个最简单的服务器

  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协议,生成响应,返回给浏览器。

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

二、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的基础上改进的协议

三、Nginx

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

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

反向代理的作用:

  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+应用程序的架构: 

其中Nginx和uWSGI之间可以通过CGI,FCGI和uwsgi协议通信,当然uwsgi的性能是最好的。

四、总结

  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

Nginx+uWSGI+Django原理(转发)的更多相关文章

  1. Nginx+uWSGI+Django原理

    Python的Web开发中,如果使用Django框架,那么较为成熟稳定的服务器架构一般是Nginx+uWSGI+Django.而为什么一定要三个结合在一起呢?直接使用Django的runserver来 ...

  2. nginx+uwsgi+django开发环境搭建

    Nginx+uWSGI+Djangoi开发环境搭建 Django简介,环境搭建 uWSGI简介,安装与配置 Nginx安装与配置 Nginx+uWSGI+Django原理解析 1.django简介,环 ...

  3. nginx+uwsgi+django 部署原理

    python开发群里经常有同学问 nginx+uwsgi+django 着了教程部署,但是不知道他们之间怎么样的关系,于是我就google到了一个让我看起来很认同的图,大家看了也比较认同,于是就分享出 ...

  4. Nginx+uwsgi+Django 的web应用环境部署-完整记录

    Python作为当前最火爆最热门,也是最主要的Web开发语言之一,在其二十多年的历史中出现了数十种Web框架,比如Django.Tornado.Flask.Twisted.Bottle和Web.py等 ...

  5. Nginx+uWSGI+Django环境配置

    通常项目会部署在虚拟环境,虚拟环境的使用可以参考这里,点击前往 当然你也可以直接部署,这里不多说. 一.安装uWSGI 1.通过pip安装 pip install uwsgi 这里只说明了一种安装方式 ...

  6. nginx+uWSGI+django+virtualenv+supervisor发布web服务器

    nginx+uWSGI+django+virtualenv+supervisor发布web服务器   导论 WSGI是Web服务器网关接口.它是一个规范,描述了Web服务器如何与Web应用程序通信,以 ...

  7. nginx + uwsgi + django/flask Nginx + php-fpm + PHP

    后端服务器设置nginx + uwsgi + django/flask需要注意的问题 - ACE开发者 https://acejoy.com/2018/09/09/547/ 后端开发应用中,除了Ngi ...

  8. 12,nginx+uWSGI+django+virtualenv+supervisor发布web服务器

    导论 WSGI是Web服务器网关接口.它是一个规范,描述了Web服务器如何与Web应用程序通信,以及Web应用程序如何链接在一起以处理一个请求,(接收请求,处理请求,响应请求) 基于wsgi运行的框架 ...

  9. nginx+uwsgi+django+supervisor+mysql+redis

    目录 1. 概述 3 2. 安装与配置 3 2.1 django项目与应用创建 3 2.2 uwsgi安装与配置 6 2.3 supervisor安装与配置 8 2.4 nginx安装与作为反向代理服 ...

随机推荐

  1. Netty快速入门(09)channel组件介绍

    书接上回,继续介绍组件. ChannelHandler组件介绍 ChannelHandler组件包含了业务处理核心逻辑,是由用户自定义的内容,开发人员百分之九十的代码都是ChannelHandler. ...

  2. window 10 安装Oracle odac 64位

    下载地址:https://www.oracle.com/cn/database/technologies/windows/downloads.html 可以下载XCopy版,也可以继续往下看下载安装文 ...

  3. jav设计模之的动态代理

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  4. spdlog 基本结构分析

    spdlog 基本结构分析 代码取自 V1.5.0, 代码堪称美学. spdlog 是一个只有头文件的C++日志库,速度非常快,扩展性很强,更重要的是 社区活跃,文档齐全. 使用 参考官方的 exam ...

  5. python爬虫——requests库使用代理

    在看这篇文章之前,需要大家掌握的知识技能: python基础 html基础 http状态码 让我们看看这篇文章中有哪些知识点: get方法 post方法 header参数,模拟用户 data参数,提交 ...

  6. WebGL简易教程(十五):加载gltf模型

    目录 1. 概述 2. 实例 2.1. 数据 2.2. 程序 2.2.1. 文件读取 2.2.2. glTF格式解析 2.2.3. 初始化顶点缓冲区 2.2.4. 其他 3. 结果 4. 参考 5. ...

  7. python接口自动化测试 - unittest框架suite、runner详细使用

    test suite 测试套件,理解成测试用例集 一系列的测试用例,或测试套件,理解成测试用例的集合和测试套件的集合 当运行测试套件时,则运行里面添加的所有测试用例 test runner 测试运行器 ...

  8. 关于Navicat连接oralcle出现Cannot load OCI DLL 87,126,193 ,ORA-28547等错误

    navicat连接oracle数据库报ORA-28547: connection to server failed, probable Oracle Net admin error错误的解决方法 na ...

  9. 「雅礼集训 2017 Day2」棋盘游戏

    祝各位圣诞后快乐(逃) 题目传送门 分析: 首先棋盘上的路径构成的图是一张二分图 那么对于一个二分图,先求出最大匹配,先手如果走到关键匹配点,只要后手顺着匹配边走,由于不再会出现增广路径,所以走到最后 ...

  10. Python学习,第五课 - 列表、字典、元组操作

    本篇主要详细讲解Python中常用的列表.字典.元组相关的操作 一.列表 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 通过下标获取元素 #先定义一个列表 le ...