当前位置: 首页 > 后端技术 > Python

PythonWeb开发重要概念辨析:CGI、WSGI、uWSGI、ASGI...

时间:2023-03-26 14:47:44 Python

在学习PythonWeb开发的时候,可能会遇到uwsgi、wsgi等名词,下面总结探讨一下它们之间的关系。CGICGI(CommonGatewayInterface)是一种协议,是外部应用程序(CGI程序)与Web服务器之间的接口标准。该协议定义了Web服务器调用外部应用程序时需要输入的参数,并给出Web服务器返回的结果。通俗地说,它规定了程序如何与Web服务器程序进行通信,从而使该程序能够在Web服务器上运行。最早的网络服务器只是响应浏览器的HTTP请求,将存储在服务器上的HTML文件返回给浏览器,即静态HTML。该场景下的服务器一般称为HTTP服务器,常见的有Apache的httpd和Nginx。事物总是在发展,网站也越来越复杂,所以才有了动态技术。但是服务器不能直接运行php、asp之类的文件,所以你不能自己做,外包给别人,但是你得和第三方做个约定,我给你什么,你再给什么会给我就是把请求参数发给你,然后我把你的处理结果发给客户端。那么这个协议就是CommonGatewayInterface,简称CGI。该协议可以用VB、C、PHP、Python实现。CGI只是一种接口协议,根本不是一种语言。引入CGI,使客户端请求可以触发Web服务器运行另一个外部程序,客户端输入的数据也会传递给这个外部程序。程序运行结束后,生成的HTML等数据会通过Web服务器端返回给客户端(即动态请求,如基于PHP、Python、Java的应用)。CGI可用于根据用户请求动态返回各种动态变化的信息给客户端。工作原理Web服务器与CGI程序的交互Web服务器会根据CGI程序的类型来决定向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_FILENAMECGI脚本的完整路径SCRIPT_NAMECGI脚本的名称SERVER_NAME这是您的Web服务器的主机名、别名或IP地址。SERVER_SOFTWARE环境变量的值包含调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix)。每当客户端请求CGI时,WEB服务器请求操作系统生成一个新的CGI解释器进程(如php-cgi.exe),一个CGI进程在处理完一个请求后退出,并在下次请求时创建一个新进程来了。当然,在访问量少,没有并发的情况下,这也是可以的。但是当访问量增加,存在并发时,这种方式就不适用了,所以FastCGIFastCGIFASTCGI是Web服务器(ex:Nginx)和语言解释器(ex:uWsgi)之间的底层通信协议规范。打开CGI的扩展。CGI的一个扩展,像一个常驻(long-live)CGI,废除了CGIfork-and-execute的工作方式(请求fork一个新的进程,处理完后再kill进程),转而使用long-lived方法减少了进程消耗并提高了性能。FastCGI会先fork一个master进程,解析配置文件,初始化执行环境,然后fork多个worker进程(类似Nginx)。当一个HTTP请求到来时,master进程会传递给一个worker进程,然后可以马上接受下一个请求,这样就避免了重复的初始化操作,效率自然提高了。并且当worker进程不够用的时候,master进程也可以根据配置预先启动几个worker进程等待;当空闲的工作进程过多时,会关闭一些,这样不仅可以提高性能,还可以节省系统资源php-fpmFastCGI只是一个协议规范,需要在各个语言中实现。PHP-FPM是FastCGI协议的PHP版本的实现。有了它,就实现了PHP脚本与Web服务器(一般是Nginx)的通信。同时,它也是一个PHPSAPI,从而在PHP解释器和Web服务器之间架起了一座桥梁。php-fpm的全称是phpfastcgiprocessmanager,即phpfastcgi进程管理器。与fastcgi静态调用cgi相比,fpm可以动态调用cgi进程并根据访问压力销毁动态调整cgi数量,有效利用内存。除此之外,还有其他优点。比如fpm也可以顺利reloadphp配置;由于fpm使用Unix-Socket与服务器通信,不需要配置cgi端口;fpm有更好的状态输出和slowlog日志,502可以给出更多的错误细节。PHP-FPM负责管理一个进程池来处理来自Web服务器的HTTP动态请求。在PHP-FPM中,master进程负责与Web服务器通信,接收HTTP请求,然后将请求转发给worker进程进行处理。worker进程主要负责动态执行PHP代码,处理完成后将处理结果返回给Web服务器,然后由Web服务器将结果发送给客户端。这就是PHP-FPMWSGI/uwsgi/uWSGI的基本工作原理在Pythonweb开发中,我们经常使用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服务器。即,用于接受客户端请求和转发响应的程序。其实一个uWSGIweb服务器,再加上Django等web框架,就已经可以实现网站的功能了。WSGIWSGI,(WEBSERVERGATEWAYINTERFACE),网络服务器网关接口,是一种网络服务器网关接口,是网络服务器(如Nginx、uWSGI等)与网络应用程序(如编写的程序)之间的一种通信方式由Flask框架)规范。目前运行在WSGI协议上的Web框架有Bottle、Flask、Django等,实现了PythonWeb程序与服务器交互的通用性。有了这个东西,web.py或者bottle或者django等Pythonweb开发框架可以很容易的部署在不同的web服务器上,不需要任何特殊的配置(并且需要一些小的配置调整)WSGI协议实际上定义了一个服务器解耦的规范和应用,即可以有多个服务器实现WSGI服务器,也可以有多个框架实现WSGI应用,那么你可以选择服务器和应用的任意组合来实现自己的Web应用。比如uWSGI和Gunicorn都是实现WSGI服务器协议的服务器,Django和Flask是实现WSGI应用协议的web框架,可以根据项目实际情况搭配使用。Flask框架和Django一样,有自己的简单WSGI服务器,一般用于服务器调试。生产环境推荐使用其他WSGI服务器。WSGI服务器有多种选择,包括uWSGI和gunicornuwsgi,它是一种类似WSGI的通信协议。uwsgiprotocol是一个uWSGI服务器自己的协议,用来定义要传输的信息类型。每个uwsgi数据包的前4个字节是对要传输的信息类型的描述。与WSGI相比,是两个不同的东西。uWSGI(server)是一个web服务器,实现了WSGI协议、uwsgi、http等协议。用于接收前端服务器转发的动态请求,处理后发送给web应用。因为无论是apache还是Nginx,它们都没有解析php等动态语言的功能,而是分配给其他模块。支持和php一样。uwsgi实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交互。uWSGI是用C语言编写的,并展示了它自己的uwsgi协议web服务器。自带丰富的组件,核心组件包括进程管理、监控、IPC等功能,实现应用服务器接口的请求插件支持多种语言和平台,如WSGI、Rack、LuaWSAPI、网管组件实现负载均衡、代理和推理功能,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服务器。负载均衡根据请求情况和Server负载,将请求分配给不同的web服务器,保证服务器性能,提高web服务器的IO性能。请求从客户端传输到Web服务器需要时间。进程长时间阻塞会持续多久?通过反向代理,请求可以完全被反向代理接受,然后传递给web服务器,保证服务器性能,一些简单的东西(比如静态文件)可以直接由反向代理处理,不需要经过web服务器总结WSGI是一种通信协议uwsgi是一种通信协议,常用于uWSGI服务器与其他网络服务器之间的数据通信uWSGI是同时实现了uwsgi和WSGI协议的web服务器百度百科说uwsgi是一种线协议不是通信协议。个人更倾向于说uwsgi是一种类似于WSGI的通信协议。uwsgi和WSGI都是基于CGI扩展的。ASGIAsynchronousGatewayProtocolInterface,网络协议服务和Python应用程序之间的标准接口,可以处理多种常见的协议类型,包括HTTP、HTTP2和WebSocket。但是目前常用的WSGI主要是为HTTP风格的请求-响应模型设计的,越来越多不遵循这种模型的协议也逐渐成为Web成为的标准之一,比如WebSocket。ASGI试图维护一个简单的应用程序接口,提供允许任何应用程序进程随时发送和接收数据的抽象。它还描述了一种与HTTP请求响应和WebSocket数据帧兼容的新序列格式。允许这些协议通过网络或本地套接字进行传输,并允许将不同的协议分配给不同的进程。WSGI和ASGI的区别WSGI是基于HTTP协议模式,不支持WebSocket,而ASGI的诞生是为了解决目前Web开发中Python常用的WSGI不支持一些新协议标准的问题。同时ASGI支持WSGI的原始模式和WebSocket的扩展,即ASGI是WSGI的扩展。