关于python:Python-Web-开发的重要概念辨析CGIWSGIuWSGIASGI……

2次阅读

共计 5938 个字符,预计需要花费 15 分钟才能阅读完成。

在学习 Python Web 开发时候,可能会遇到诸如 uwsgi、wsgi 等名词,上面通过梳理总结,探索它们之间的关系。

CGI

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 程序通过规范输出(STDIN)和规范输入(STDOUT)来进行输入输出。此外 CGI 程序还通过环境变量来失去输出,操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序能够存取它们。Web 服务器和 CGI 接口又另外设置了一些环境变量,用来向 CGI 程序传递一些重要的参数。

罕用 CGI 环境变量:

变量名 形容
CONTENT_TYPE 这个环境变量的值批示所传递来的信息的 MIME 类型。目前,环境变量 CONTENT_TYPE 个别都是:application/x-www-form-urlencoded, 他示意数据来自于 HTML 表单。
CONTENT_LENGTH 如果服务器与 CGI 程序信息的传递形式是 POST,这个环境变量即便从规范输出 STDIN 中能够读到的无效数据的字节数。这个环境变量在读取所输出的数据时必须应用。
HTTP_COOKIE 客户机内的 COOKIE 内容。
HTTP_USER_AGENT 提供蕴含了版本数或其余专有数据的客户浏览器信息。
PATH_INFO 这个环境变量的值示意紧接在 CGI 程序名之后的其余门路信息。它经常作为 CGI 程序的参数呈现。
QUERY_STRING 如果服务器与 CGI 程序信息的传递形式是 GET,这个环境变量的值即便所传递的信息。这个信息经跟在 CGI 程序名的前面,两者两头用一个问号’?’分隔。
REMOTE_ADDR 这个环境变量的值是发送申请的客户机的 IP 地址,例如下面的 192.168.1.67。这个值总是存在的。而且它是 Web 客户机须要提供给 Web 服务器的惟一标识,能够在 CGI 程序中用它来辨别不同的 Web 客户机。
REMOTE_HOST 这个环境变量的值蕴含发送 CGI 申请的客户机的主机名。如果不反对你想查问,则无需定义此环境变量。
REQUEST_METHOD 提供脚本被调用的办法。对于应用 HTTP/1.0 协定的脚本,仅 GET 和 POST 有意义。
SCRIPT_FILENAME CGI 脚本的残缺门路
SCRIPT_NAME CGI 脚本的的名称
SERVER_NAME 这是你的 WEB 服务器的主机名、别名或 IP 地址。
SERVER_SOFTWARE 这个环境变量的值蕴含了调用 CGI 程序的 HTTP 服务器的名称和版本号。例如,下面的值为 Apache/2.2.14(Unix)

每当客户申请 CGI 的时候,WEB 服务器就申请操作系统生成一个新的 CGI 解释器过程(如 php-cgi.exe),CGI 的一个过程则解决完一个申请后退出,下一个申请来时再创立新过程。

当然,这样在访问量很少没有并发的状况也行。但当访问量增大,并发存在,这种形式就不适宜了,于是就有了 FastCGI

FastCGI

FASTCGI 是 Web 服务器(ex:Nginx)和语言解释器(ex:uWsgi)两者底层的通信协议的标准,是对 CGI 的凋谢的扩大。

CGI 的一个扩大,像是一个常驻(long-live)型的 CGI,破除了 CGI fork-and-execute(来一个申请 fork 一个新过程解决,解决完再把过程 kill 掉)的工作形式,转而应用一种长生存期的办法,缩小了过程耗费,晋升了性能。

而 FastCGI 则会先 fork 一个 master 过程,解析配置文件,初始化执行环境,而后再 fork 多个 worker 过程(与 Nginx 有点像),当 HTTP 申请过去时,master 过程将其会传递给一个 worker 过程,而后立刻能够承受下一个申请,这样就防止了反复的初始化操作,效率天然也就进步了。

而且当 worker 过程不够用时,master 过程还能够依据配置事后启动几个 worker 过程等着;当闲暇 worker 过程太多时,也会关掉一些,这样不仅进步了性能,还节约了系统资源

php-fpm

FastCGI 只是一个协定标准,须要每个语言具体去实现,PHP-FPM 就是 PHP 版本的 FastCGI 协定实现 ,有了它,就是实现 PHP 脚本与 Web 服务器(通常是 Nginx)之间的通信,同时它也是一个 PHP SAPI,从而构建起 PHP 解释器与 Web 服务器之间的桥梁。

Php-fpm 全称是 php fastcgi process manager 即 php fastcgi 过程管理器,相比 fastcgi 动态的唤起 cgi,fpm 能依据拜访的压力动静的唤起 cgi 过程和销毁以达到动静的调整 cgi 数量,这样能够无效的应用内存。

除此之外还有其它的一些长处,比方,fpm 还能够平滑的重载 php 配置;因为 fpm 是应用 Unix-Socket 来和服务器通信,所以也不必再配置 cgi 端口;fpm 有更好的状态输入和 slowlog 日志,502 的时候能给出更多的谬误细节。

PHP-FPM 负责管理一个过程池来解决来自 Web 服务器的 HTTP 动静申请,在 PHP-FPM 中,master 过程负责与 Web 服务器进行通信,接管 HTTP 申请,再将申请转发给 worker 过程进行解决,worker 过程次要负责动静执行 PHP 代码,解决实现后,将处理结果返回给 Web 服务器,再由 Web 服务器将后果发送给客户端。这就是 PHP-FPM 的根本工作原理

WSGI / uwsgi / uWSGI

在 Python Web 开发中,咱们常常应用 Uwsgi 配合 Nginx 部署一个 Web 框架,如 Django 或 flask。同时咱们又会说,框架和 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 框架,就曾经能够实现网站的性能了。

WSGI

WSGI,(WEB SERVER GATEWAY INTERFACE),Web 服务器网关接口,是一种 Web 服务器网关接口,它是一个 Web 服务器(如 Nginx,uWSGI 等服务器)与 Web 利用(如 Flask 框架写的程序)通信的一种标准。 以后运行在 WSGI 协定之上的 Web 框架有 Bottle,Flask,Django

实现了 Python Web 程序与服务器之间交互的通用性。有了这个货色,web.py 或者 bottle 或者 django 等等的 Python Web 开发框架,就能够轻松地部署在不同的 Web server 上了,不须要做任何非凡配置(也须要一些小小的配置调整)

WSGI 协定其实是定义了一种 server 与 application 解耦的标准,即能够有多个实现 WSGI server 的服务器,也能够有多个实现 WSGI application 的框架,那么就能够抉择任意的 server 和 application 组合实现本人的 Web 利用。

例如 uWSGI 和 Gunicorn 都是实现了 WSGI server 协定的服务器,Django,Flask 是实现了 WSGI application 协定的 Web 框架,能够依据我的项目理论状况搭配应用。

像 Django,Flask 框架都有本人实现的简略的 WSGI server,个别用于服务器调试,生产环境下倡议用其余 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 框架写了一个网站,当初要将它挂在网上运行,咱们个别须要:

  • Nginx 做为代理服务器:负责动态资源发送(js、css、图片等)、动静申请转发以及后果的回复。
  • uWSGI 做为后端服务器:负责接管 Nginx 转发的申请并解决后发给 Django 利用以及接管 Django 利用返回信息转发给 Nginx。
  • Django 利用收到申请后处理数据并渲染相应的返回页面给 uWSGI 服务器。

一个 Django 利用,通过 WSGI 协定连贯 uWSGI 服务器,uWSGI 服务器实现 WSGI、http 等协定,通过 uwsgi 协定和 Nginx 服务器实现 http 的动静申请和转发以及后果

问题:有 uWGSI 了,Django 为什么还须要 Nginx?

一个一般的集体网站,访问量不大的话,当然能够由 uWSGI 和 Django 形成。然而一旦拜访量过大,客户端申请连贯就要进行长时间的期待。这个时候就进去了分布式服务器,咱们能够多来几台 Web 服务器,都能解决申请。

然而谁来调配客户端的申请连贯和 Web 服务器呢?Nginx 就是这样一个管家的存在,由它来调配。这也就是由 Nginx 实现反向代理,即代理服务器。

Nginx 是一个 HTTP 和反向代理服务器

  • 正向代理:正向的就是由浏览器被动的想代理服务器发出请求,经代理服务器做出解决后再转给指标服务器
  • 反向代理:反向的就是不论浏览器同不批准,申请都会通过代理服务器解决再发给指标服务器

应用 Nginx 作为反向代理服务器的益处:

  • 平安

不论什么申请都要通过代理服务器,能够防止内部程序间接攻打 Web 服务器

  • 负载平衡

依据申请状况和服务器负载状况,将申请调配给不同的 Web 服务器,保障服务器性能

  • 进步 Web 服务器的 IO 性能

申请从客户端传到 Web 服务器是须要工夫的,传递多长时间就会让这个过程阻塞多长时间,而通过反向代理,就能够由反向代理残缺承受该申请,而后再传给 Web 服务器,从而保障服务器性能,而且有的一些简略的事件(比方动态文件)能够间接由反向代理解决,不通过 Web 服务器

总结

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

百度百科上说 uwsgi 是一种线路协定而不是通信协议,集体更偏向于 uwsgi 是相似 WSGI 的通信协议的说法,uwsgi 和 WSGI 都是基于 CGI 扩大进去的。

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 的扩大。

正文完
 0