CGI
、FastCGI
、PHP-CGI
、PHP-fpm
今天我们来聊一下 CGI
、FastCGI
、PHP-CGI
、PHP-fpm
这四个概念
CGI
通用网关接口(Common Gateway Interface)即 CGI
,是一种网关协议,是外部应用程序(CGI 程序)与 Web 服务器之间的接口标准,是在 CGI 程序和 Web 服务器之间传递信息的规程
通俗一点来讲,PHP
、Java
、Python
等喜欢和 Web 服务器(Apache
, Nginx
等)聊天,但是每个人说的语言都不一样,所以说这个时候我们的 CGI
童鞋就勇敢的站出来充当这个翻译官的身份,把各个语言都翻译为统一的 web server 能懂的语言,这就是 CGI
的作用了 ~ ~ ~
CGI
本质还是一个协议,他允许 web server 执行外部程序,并且将程序输出内容传递给 web server
CGI
在遇到外部请求时会先 fork 出一个 CGI
子进程,然后处理请求,执行完毕后再结束这个子进程,这就是所谓的 fork-and-execute
模式,这样的话,有多少的请求,就会出现多少个子进程,子进程的反复加载,每次都会初始化执行环境,造成了很多不必要的开销,导致了 CGI
的性能低下
如何解决这个问题呢?那就该我们的 FastCGI
登场了 ~ ~ ~
FastCGI
FastCGI
是一个可伸缩地、高速地在 HTTP server 和动态脚本语言间通信的接口,可以理解为 CGI
的升级版
通俗一点来讲,还是上述的那个场景,CGI
每翻译一次都要去书里面查找资料,导致翻译效率太低,于是乎,FastCGI
就来了,他记忆力比较好,看一遍就能背下来,所以只需要第一次去记下来,之后就能高效的进行工作 ~ ~ ~
因为 CGI
每次都会重新加载,重新初始化执行环境,重新启动脚本解析器,导致了性能低下,FastCGI
像是一个常驻(long-live)型的 CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去 fork 一次,如果 CGI
解释器保持在内存中并接受 FastCGI
进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over 特性等等
FastCGI
接口方式采用 C/S 结构,可以将 HTTP 服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当 HTTP 服务器每次遇到动态程序时,可以将其直接交付给 FastCGI
进程来执行,然后将得到的结果返回给浏览器。这种方式可以让 HTTP 服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。
一般情况下,FastCGI的整个工作流程是这样的:
Web Server 启动时载入
FastCGI
进程管理器FastCGI
进程管理器自身初始化,启动多个CGI
解释器进程(多个php-cgi)并等待 Web server 的连接当客户端请求到达 Web Server 时,
FastCGI
进程管理器选择并连接到一个CGI
解释器。Web server 将 CGI 环境变量和标准输入发送到FastCGI
子进程php-cgi
FastCGI
子进程完成处理后将标准输出和错误信息从同一连接返回 Web Server。当FastCGI
子进程关闭连接时,请求便告处理完成。FastCGI
子进程接着等待并处理来自FastCGI
进程管理器(运行在 Web Server 中)的下一个连接
PHP-CGI
PHP-CGI
是 PHP 自带的 FastCGI
管理器
PHP 的解释器是 php-cgi
,php-cgi
只是个 CGI
程序,他自己本身只能解析请求
不足之处在于,更改 php.ini 配置后需重启 php-cgi 才能让新的 PHP 配置生效,不可以平滑重启
PHP-fpm
FastCGI
的特点是会在一个进程中依次完成多个请求,以达到提高效率的目的,大多数 FastCGI
实现都会维护一个进程池。
而 PHP-fpm
就是针对于 PHP 的 FastCGI
的一种实现,他负责管理一个进程池,来处理来自 Web 服务器的请求。目前,PHP-fpm
是内置于 PHP 的。
但是 PHP-fpm
仅仅是个”PHP FastCGI 进程管理器”, 它仍会调用 PHP 的解释器本身来处理请求
PHP-fpm
提供了更好的 PHP 进程管理方式,可以有效控制内存和进程、可以平滑重载 PHP 配置
PHP-fpm
的使用非常方便,配置都是在 PHP-fpm.ini
的文件内,而启动、重启都可以从 php/sbin/PHP-fpm
中进行。更方便的是修改 php.ini 后可以直接使用 PHP-fpm reload
进行加载,无需杀掉进程就可以完成 php.ini 的修改加载
PHP-fpm
是守护 php-cgi
的进程管理器。