CGI、WSGI、uWSGI、ASGI概念和Django项目部署架构的关系

学习Python Web 开发的时候,经常遇到一些名词:uwsgi、wsgi,今天整理一下。

CGI(Common Gateway Interface)通用网关接口

顾名思义,CGI(Common Gateway Interface)通用网关接口,它是一个协议,是外部应用程序(CGI 程序)与Web服务器之间的接口标准,该协议定义了 Web 服务器调用外部应用程序的时候需要输入的参数以及给Web服务器的返回结果。

通俗地讲,它规定一个程序应当如何与Web服务器程序进行通信,让这个程序可以跑在Web服务器上。

  • 起源: 最早的Web服务器只是简单地响应浏览器发来的http请求,并将存储在服务器上的html文件返回给浏览器,也就是静态的HTML。这个场景下的服务器一般被称为 HTTP 服务器,常见的有Apache的httpd和Nginx。

    时代进步,技术也在发展,网站开始越来越复杂,所以出现动态技术。但是服务器并不能直接运行 php、asp这样的文件。既然自己做不了,那就外包给别人吧,前提是要与第三方协商好一个约定:我给你什么,然后你给我什么,也就是我把请求参数发送给你,然后我接收你的处理结果给客户端。

    这个**约定就是 Common Gateway Interface,简称 CGI。**这个协议可以用 VB、C、PHP、Python 来实现。CGI只是接口协议,根本不是什么语言。

  • 发展:引入了CGI,客户端请求能够触发Web服务器去运行另一个外部程序,客户端所发送的请求数据也会传给这个外部程序,该程序运行结束后会将生成的 HTML 和其他数据通过Web服务器再返回给客户端(即动态请求,比如基于 PHP、Python、Java 实现的应用)。利用 CGI 可以针对用户请求,动态返回给客户端各种各样动态变化的信息。

  • 工作原理:Web服务器与CGI程序的交互
    Web 服务器将根据CGI程序的类型决定数据向CGI程序传送的方式,一般是通过标准输入/输出流和环境变量来与 CGI 程序间传递数据。如下图所示:
    CGI-http

    环境变量是由操作系统提供的,它们定义了程序的执行环境,应用程序可以存取它们。
    Web服务器和CGI接口又另设置了一些环境变量,用来向 CGI 程序传递一些重要的参数。
    

params

  • 每当客户端请求CGI的时候,Web服务器就向操作系统请求生成一个新的CGI解释器进程(如 php-cgi.exe),CGI的一个进程处理完一个请求后退出,下一个请求来时再创建新进程。
    当然,这样在访问量很少、没有并发的情况还行。但是当访问量增大,并发存在,这种方式就不适合了,于是就有了FastCGI

FastCGI

  • FastCGI是Web服务器(例如Nginx)和语言解释器(例如 uWsgi)两者底层的通信协议的规范,是对CGI的拓展。它像是一个常驻(long-live)型的CGI ,废除了 CGI fork-and-execute(来一个请求 fork 一个新进程处理,处理完再把进程 kill 掉)的工作方式,转而使用一种较长生存期的方法,减少进程消耗,提升了性能。
  • FastCGI 会先 fork 一个 master 进程,解析配置文件,初始化执行环境,然后再 fork 多个 worker 进程(与 Nginx 有点像),当 HTTP 请求过来时,master 进程将其会传递给一个 worker 进程,然后立即可以接受下一个请求,这样就避免了重复的初始化操作,效率自然也就提高了。当 worker 进程不够用时,master 进程还可以根据配置预先启动几个 worker 进程等着;当空闲 worker 进程太多时,也会关掉一些,这样不仅提高了性能,还节约了系统资源。
  • 但是,FastCGI仍然只是一个协议规范,需要每种编程语言去实现。
  • 例如PHP-FPM 就是 PHP 版本的 FastCGI 协议实现,有了它,就是实现 PHP 脚本与 Web 服务器(通常是 Nginx)之间的通信,同时它也是一个 PHP SAPI,从而构建起 PHP 解释器与 Web 服务器之间的桥梁。这里就不展开讲了,下面的才是重头戏。

WSGI / uwsgi / uWSGI

  • 在 Python Web 开发中经常使用 uWSGI 配合 Nginx 部署一个 Web 框架,如 Django 或 flask。同时,Web框架和Web服务器之间要符合 WSGI 协议。

  • 先来厘清这几个概念。

  • Web 服务器和 Web框架

在讲 uWSGI 和 WSGI 之前,先要弄清楚Web开发的两大块:Web服务器和Web框架。

Web服务器:即用来接受客户端请求,建立连接,转发响应的程序。至于转发的内容是什么,交由Web框架来处理,即处理这些业务逻辑。比如查询数据库、生成实时信息等。Nginx就是一个Web服务器,Django或flask就是Web框架。

  • 如何实现uWSGI和WSGI的配合呢?如何做到任意一个Web服务器,都能搭配任意一个框架呢?这就产生了WSGI协议
  • 只要Web服务器和Web框架满足WSGI协议,它们就能相互搭配。所以WSGI只是一个协议,一个约定。而不是Python的模块、框架等具体的功能。
  • 而uWSGI,它是实现了WSGI协议的一个Web服务器。即用来接受客户端请求,转发给响应的程序。实际上,一个uWSGI的Web服务器,再加上Django这样的Web框架,就已经可以实现网站的功能了。那为什么还经常搭配上Nginx服务器呢,答案在FastCGI那一部分已经有了。
  • WSGI协议 :Web Server Gateway Interface,是一种Web服务器网关接口,它是一个Web服务器(如Nginx,uWSGI等服务器)与Web应用(如Django 框架写的程序)一种通信规范。当前运行在WSGI协议之上的Web框架有很多:Flask,Django等。它实现了Python Web程序与服务器之间交互的通用性。有了这个东西,web.py或者bottle或者django等等的Python Web开发框架,就可以轻松地部署在不同的Web server上了,不需要做任何特殊配置(一些小的配置调整)。
    uwsgi
  • WSGI协议其实是定义了一种web server与应用app解耦的规范,即可以有多个实现WSGI server的服务器,也可以有多个实现WSGI application的框架,那么就可以选择任意的server和application组合实现自己的Web应用。

例如 uWSGI和 Gunicorn都是实现了WSGI server协议的服务器,Django,Flask是实现了WSGI application协议的Web框架,可以根据项目实际情况搭配使用。

像Django,Flask框架都有自己实现的简单的WSGI server,一般用于服务器调试(例如Django的runserver命令其实就是运行的自己的wsgi模块,名称叫wsgiref),生产环境下建议用其他WSGI server,WSGI服务器的选择很多,包括uWSGI和gunicorn。

  • uwsgi:同WSGI一样是一种通信协议,uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet的前4byte为传输信息类型描述,它与WSGI相比是两样东西。
  • uWSGI (服务器):它是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。用于接收前端服务器转发的动态请求并处理后发给Web应用程序。

因为apache也好,Nginx也罢,它们自己都没有解析动态语言如php的功能,而是分派给其他模块来做,比如apache就可以说内置了php模块,支持的非常爽,让人感觉好像apache就支持php一样。uwsgi实现了WSGI协议、uwsgi、http等协议。
Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
uWSGI是使用C语言实现了uwsgi协议的Web服务器。它自带丰富的组件,其中核心组件包含进程管理、监控、IPC等功能,实现应用服务器接口的请求插件支持多种语言和平台,比如WSGI、Rack、Lua WSAPI,网管组件实现了负载均衡、代理和理由功能

  • uWSGI也可以当做中间件。

如果是Nginx+uWSGI+App,那uWSGI就是一个中间件
如果是uWSGI+App,那它就是服务器

  • Nginx+uWGSI:假如我们使用Python 的Django 框架写了一个网站,现在要将它挂在网上运行,我们一般需要:
    1、Nginx 做为代理服务器:负责静态资源发送(js、css、图片等)、动态请求转发以及结果的回复。
    2、uWSGI 做为后端服务器:负责接收 Nginx 转发的请求并处理后发给 Django 应用以及接收 Django 应用返回信息转发给 Nginx。
    3、Django 应用收到请求后处理数据并渲染相应的返回页面给 uWSGI 服务器。

一个Django应用,通过WSGI协议连接uWSGI服务器,uWSGI服务器实现WSGI、http等协议,通过uwsgi协议和Nginx服务器实现http的动态请求转发以及响应。
django-uwsgi

  • ASGI:异步网关协议接口,一个介于网络协议服务和Python应用之间的标准接口,能够处理多种通用的协议类型,包括HTTP,HTTP2和WebSocket。

然而目前常用的WSGI主要是针对HTTP风格的请求响应模型做的设计,并且越来越多的不遵循这种模式的协议逐渐成为Web变成的标准之一,例如WebSocket。

  • ASGI尝试保持在一个简单的应用接口的前提下,提供允许数据能够在任意的时候、被任意应用进程发送和接受的抽象。并且同样描述了一个新的,兼容HTTP请求响应以及WebSocket数据帧的序列格式。允许这些协议能通过网络或本地socket进行传输,以及让不同的协议被分配到不同的进程中。
  • WSGI和ASGI的区别:WSGI是基于HTTP协议模式的,不支持WebSocket,而ASGI的诞生则是为了解决Python常用的WSGI不支持当前Web开发中的一些新的协议标准。同时,ASGI对于WSGI原有的模式的支持和WebSocket的扩展,即ASGI是WSGI的扩展。

总结

  • WSGI是一种通信协议
  • uwsgi是一种通信协议,常用于在uWSGI服务器与其他网络服务器的数据通信
  • uWSGI是实现了uwsgi和WSGI两种协议的Web服务器

Django框架的服务器架构一般是 Nginx + uWSGI + Django,那么问题来了

有 uWGSI 了,Django 为什么还需要 Nginx?

  • 前面提到的Django框架自带的uwsgi模块:wsgiref模块。
  • 这个模块监听8000端口,把Http请求,根据WSGI协议,转换application函数中的environ参数,然后调用application函数。 wsgiref会把application函数提供的响应头设置转换为HTTP协议的响应头,把application的返回(return)作为响应体,根据HTTP协议,生成响应,返回给浏览器。

  • 但是它结构太简单,最后也就是只适合用于测试和学习的简单WSGI服务器模块。

Django 本身提供了runserver,为什么不能用来部署?而是使用nginx+uWSGI部署?

  • runserver 方法是调试Django 时经常用到的运行方式,它使用Django 自带的WSGI Server 运行,主要在测试和开发中使用,并且runserver 开启的方式也是单进程。
  • uWSGI 是一个Web 服务器,它实现了WSGI 协议(web服务网关接口)、uwsgi(线路协议)、http 等协议。注意uwsgi 是一种通信协议,而uWSGI 是实现uwsgi 协议和WSGI 协议的Web 服务器。uWSGI 具有超快的性能、低内存占用和多app 管理等优点,并且搭配着Nginx 就是一个生产环境了,能够将用户访问请求与应用app 隔离开,实现真正的部署。相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。

为什么要使用Nginx 来做负载均衡?

  • Nginx能做什么:

安全(Nginx 作为专业服务器,暴露在公网相对比较安全)
能更好地处理静态资源(一些http request header)
Nginx也可以缓存一些动态内容Nginx可以更好地配合CDN
可以进行多台机器的负载均衡

  • 当然,如果访问量不大,其实也没必要加个Nginx,uWSGI足以胜任。
  • Nginx 和uWISG 服务器之间如何配合工作的?
    (1)首先浏览器发起http 请求到nginx 服务器
    (2)Nginx 根据接收到请求包,进行url 分析,判断访问的资源类型,如果是静态资源,直接读取静态资源返回给浏览器
    (3)如果请求的是动态资源就转交给uwsgi服务器,uwsgi 服务器根据自身的uwsgi 和WSGI 协议,找到对应的Django 框架。
    (4)Django 框架下的应用进行逻辑处理后,将返回值发送到uwsgi 服务器,然后uwsgi 服务器再返回给nginx。
    (5)最后nginx将返回值返回给浏览器进行渲染显示给用户。

Django网站架构图

summary

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值