CGI
CGI
网关接口(Common Gateway Interface),是外部应用程序(CGI
程序) 与Web服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的规程。
比如你的网站是用 python 写的那么 CGI 就是链接 python程序与 Nginx之间的桥梁. 它的实现方式最为简单,跨平台性极佳,所有的web server
都支持.
CGI方式在遇到连接请求(用户请求)先要创建CGI
的子进程,激活一个CGI
进程,然后处理请求,处理完后结束这个子进程。这就是 fork-and-execute
模式。
所以用CGI
方式的服务器有多少连接请求就会有多少CGI
子进程,子进程反复加载是CGI
性能低下的主要原因。当用户请求数量非常多时,会大量挤占系统的资源如内存,
CPU时间等,造成效能低下。
- CGI脚本工作流程::
- 1.浏览器通过HTML表单或超链接请求指向一个CGI应用程序的URL。
- 2.服务器收发到请求。
- 3.服务器执行所指定的CGI应用程序。
- 4.CGI应用程序执行所需要的操作,通常是基于浏览者输入的内容。
- 5.CGI应用程序把结果格式化为网络服务器和浏览器能够理解的文档(通常是HTML网页)。
- 6.网络服务器把结果返回到浏览器中。
优点:
- 平台独立性.
- 目前几乎所有的web服务器都支持.
- 几乎所有的语言都支持.
缺点:
这种
fork-and-execute
模式一直都保守诟病,原因是不管是基于线程还是进程,OS层面能够容纳的线程/进程数量是有限的,而且多线程之间会争抢CPU时间, CPU会疲于应付各个线程之间的调度,这样珍贵的CPU资源被大量浪费了.而且线程数会随着请求数直线飙升,稳定性也成问题.如果遇到长IO任务,这一弊端更为明显. 分分钟让你的操作系统崩溃.
FastCGI
FastCGI
是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,
同时,FastCGI也被许多脚本语言所支持相比传统 CGI
模式 FastCGI
采用常驻进程的方式避免了每次请求都会创建 销毁进程所带来的不必要的消耗.它是一种
长生命周期的程序,一旦启动便会驻留在系统里,每当遇到新的请求只需将这个请求的内容直接发送至 FastCGI
监听的端口剩下的由你的程序处理,当处理完成后
返回结果给 Nginx即可.但要注意的是你需要为你的常驻进程建立对应的守护进程,避免因错误而导致的进程崩溃退出.这种方式可以让HTTP服务器专一地处理静态请求
或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能与稳定新.
- FastCGI的工作流程::
- 1.Web Server启动时载入FastCGI进程管理器 (如 spawn-cgi)
- 2.FastCGI进程管理器自身初始化,启动多个CGI解释器进程并等待来自Web Server的连接。
- 3.当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程。
- 4.FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。
Spawn-FCGI:
Spawn-FCGI是一个通用的FastCGI管理服务器,它是lighttpd中的一部份,很多人都用Lighttpd的Spawn-FCGI进行FastCGI模式下的管理工作,不过有不少缺点 。而PHP-FPM的出现多少缓解了一些问题,但PHP-FPM有个缺点就是要重新编译,这对于一些已经运行的环境可能有不小的风险),在php 5.3.3中可以直接使用PHP-FPM了。 Spawn-FCGI的代码很少,全部才630行,用c语言编写,最近一次提交是5年前。代码主页:https://github.com/lighttpd/spawn-fcgi
Spawn-FCGI代码分析如下:
-
spawn-fcgi 首先create socket,bind,listen 3步创建服务器socket,(把这个socket叫做 fcgi_fd)
-
用dup2,把fcgi_fd 交换给 FCGI_LISTENSOCK_FILENO (FCGI_LISTENSOCK_FILENO数值上等于0,这是fastcgi协议当中指定用来listen的socket id)
- 执行execl ,replaces the current process image with a new process image. process image 进程在运行空间的代码段
Spawn-FCGI功能很单一:
只管fork进程,子进程挂了,主进程仅仅log记录一次,根本不会重新fork。
apache 模块方式:
记得曾在xp 配置 apache + php ,会在apache 配置下面一段:
LoadModule php5_module C:/php/php5apache2_2.dll
模块方式 其实就是将某种语言的解释器 内置进webserver中,其效率比 CGI桥接的方式高一点,(因为毕竟省略了通信的消耗) 比如 mod_php5.so/ php5apache2.dll 就是将所包含的自定义函数,通过Hook机制注入到Apache中,在Apache处理流程的各个阶段负责处理php请求。
WSGI:
WSGI
是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI
被开发出来以后,许多其它语言中也出现了类似接口。
WSGI
是作为Web服务器与Web应用程序或应用框架之间的一种低级别的接口,以提升可移植Web应用开发的共同点。WSGI
是基于现存的CGI标准而设计的。你可以简单
理解 WSGI是基于 CGI标准的封装,目的之将CGI功能中,一些可复用的东西抽离出来.
WSGI uwsgi uWSGI 之间什么关系:
WSGI
uwsgi
CGI
其实指的是某种协议,注意是协议,并不是具体实现 也就是说任何满足协议规范的程序都可以用于这些协议的实现.
uWSGI
是一种web服务器软件 (和nginx , apache 等更类似),它是一种有具体功能的软件.uWSGI 项目旨在为部署分布式集群的网络应用开发一套完整的解决方案。
uWSGI主要面向web及其标准服务,已经成功的应用于多种不同的语言。由于uWSGI的可扩展架构,它能够被无限制的扩展用来支持更多的平台和语言。
目前,你可以使用C,C++和Objective-C来编写插件。项目名称中的“WSGI”是为了向同名的Python Web标准表示感谢,因为WSGI为该项目开发了第一个插件。
uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。uWSGI,既不用wsgi协议也不用FastCGI协议,而是自创了一个uwsgi
的协议,
uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,
它与WSGI相比是两样东西。据说该协议大约是fcgi协议的10倍那么快。
-
uWSGI的主要特点如下:
- 超快的性能。
- 低内存占用(实测为apache2的mod_wsgi的一半左右)。
- 多app管理.
- 详尽的日志功能(可以用来分析app性能和瓶颈)
- 高度可定制(内存大小限制,服务一定次数后重启等)
举了例子(使用 uWSGI 部署 Django 程序):
1.你需要安装 uwsgi
epel-release 上有
yum install uswgi
2.部署你的uWSGI:
uwsgi
--socket 127.0.0.1:9003
--processes 2
--chdir /webroot/record/record
--pp .. -w wsgi
--daemonize /weblog/record.log
具体关于 uWSGI的信息 可以看这里: http://projects.unbit.it/uwsgi/wiki/Example