CGI、FastCGI、WSGI、uwsgi、uWSGI
CGI、FastCGI、WSGI、uwsgi、uWSGI 的联系与区别。
CGI、FastCGI、WSGI、uwsgi、uWSGI
CGI
CGI 简介
CGI,(Common Gateway Interface)通用网关接口,是一个协议,是外部应用程序(CGI 程序)与 WEB 服务器之间的接口标准,该协议定义了 Web 服务器调用外部应用程序的时候需要输入的参数和给 Web 服务器的返回结果。
最早的 Web 服务器简单地响应浏览器发来的 HTTP 请求,并将存储在服务器上的 HTML 文件返回给浏览器,也就是静态 html。随着不断地发展,网站也越来越复杂,所以出现动态技术。但是服务器并不能直接运行 php,asp 这样的文件,自己不能做,外包给别人吧,但是要与第三做个约定,我给你什么,然后你给我什么,就是我把请求参数发送给你,然后我接收你的处理结果给客户端。那这个约定就是 common gateway interface,简称 cgi。这个协议可以用 vb,c,php,python 来实现。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 工作原理
每当客户请求 CGI 的时候,WEB 服务器就请求操作系统生成一个新的 CGI 解释器进程(如 php-cgi.exe),CGI 的一个进程则处理完一个请求后退出,下一个请求来时再创建新进程。当然,这样在访问量很少没有并发的情况也行。但当访问量增大,并发存在,这种方式就不适合了,于是就有了 FastCGI。
FastCGI
FastCGI 简介
CGI 的一个扩展,像是一个常驻(long-live)型的 CGI ,废除了 CGI fork-and-execute (来一个请求 fork 一个新进程处理,处理完再把进程 kill 掉)的工作方式,转而使用一种长生存期的方法,减少了进程消耗,提升了性能。
FastCGI 工作原理
- (1)Web Server 启动时载入 FastCGI 进程管理器(IIS ISAPI 或 Apache Module)
- (2)FastCGI 进程管理器自身初始化,启动多个 CGI 解释器进程(可见多个 php-cgi)并等待来自 Web Server 的连接。
- (3)当客户端请求到达 Web Server 时,FastCGI 进程管理器选择并连接到一个 CGI 解释器。Web server 将 CGI 环境变量和标准输入发送到 FastCGI 子进程 php-cgi。
- (4)FastCGI 子进程完成处理后将标准输出和错误信息从同一连接返回 Web Server。当 FastCGI 子进程关闭连接时,请求便被告知处理完成。FastCGI 子进程接着等待并处理来自 FastCGI 进程管理器(运行在 Web Server 中)的下一个连接。在 CGI 模式中, php-cgi 在此便退出了。
WSGI
WSGI,(WEB SERVER GATEWAY INTERFACE),Web 服务器网关接口,是一种 Web 服务器网关接口,它是一个 Web 服务器(如 Nginx,uWSGI 等服务器)与 web 应用(如 Flask 框架写的程序)通信的一种规范。
当前运行在 WSGI 协议之上的 Web 框架有 Bottle,Flask,Django
uwsgi
uwsgi 是一种线路协议,是 uWSGI 服务器的独占协议,用于定义传输信息的类型(type of information),每一个 uwsgi packet 前4 byte 为传输信息类型的描述,与 WSGI 协议是两种东西。
对于 uwsgi,个人比较认同 https://baijiahao.baidu.com/s?id=1590941335729952485&wfr=spider&for=pc 的观点,"它是用于前端服务器与 uwsgi 的通信规范,相当于 FastCGI 的作用"。
uWSGI
uWSGI 是一个 Web 服务器,它实现了 WSGI 协议、uwsgi、http等协议。
uWSGI 也可以当做中间件。
- 如果是 Nginx+uWSGI+App,那 uWSGI 就是一个中间件
- 如果是 uWSGI+App,那它就是服务器
区分 WSGI、uwsgi、uWSGI
- WSGI 是一种通信协议
- uwsgi 是一种通信协议,常用于在 uWSGI 服务器与其他网络服务器的数据通信
- 而 uWSGI 是实现了 uwsgi 和 WSGI 两种协议的Web服务器
百度百科上说 uwsgi 是一种线路协议而不是通信协议,个人更倾向于 uwsgi 是类似 WSGI 的通信协议的说法,uwsgi 和 WSGI 都是基于 CGI 扩展出来的。
这些名词的关系
假设我们使用 python 的 Django 框架写了一个网站,现在要将它挂在网上运行,我们一般需要:
- Nginx 做为代理服务器:负责静态资源发送(js、css、图片等)、动态请求转发以及结果的回复。
- uWSGI 做为后端服务器:负责接收 Nginx 转发的请求并处理后发给 Django 应用以及接收 Django 应用返回信息转发给 Nginx。
- Django 应用收到请求后处理数据并渲染相应的返回页面给 uWSGI 服务器。
有 uWGSI 了 Django 为什么还需要 Nginx
Nginx 是一个 HTTP 和反向代理服务器
正向代理
正向的就是由浏览器主动的想代理服务器发出请求,经代理服务器做出处理后再转给目标服务器
反向代理
反向的就是不管浏览器同不同意,请求都会经过代理服务器处理再发给目标服务器
更多关于正向代理和反向代理的内容可参考:
使用 Nginx 作为反向代理服务器的好处:
安全
不管什么请求都要经过代理服务器,可以避免外部程序直接攻击 Web 服务器
负载均衡
根据请求情况和服务器负载情况,将请求分配给不同的 Web 服务器,保证服务器性能
提高 Web 服务器的 IO 性能
请求从客户端传到 Web 服务器是需要时间的,传递多长时间就会让这个进程阻塞多长时间,而通过反向代理,就可以由反向代理完整接受该请求,然后再传给 Web 服务器,从而保证服务器性能,而且有的一些简单的事情(比如静态文件)可以直接由反向代理处理,不经过 Web 服务器
References
https://www.cnblogs.com/wanghetao/p/3934350.html
https://baike.baidu.com/item/fastcgi/10880685
https://www.jianshu.com/p/679dee0a4193
https://baijiahao.baidu.com/s?id=1590941335729952485&wfr=spider&for=pc