php PHP-CGI CLI
CLI
CLI (Command Line Interface) 既命令行接口,可以直接在命令行下运行php脚本,与下面几种模式无关,比如:
模块化
还记得当年第一次配置apache的时候么?那个时候还不知道什么nginx,不知道fast-cgi,当年配置apche最重要的一环是什么?
还记得这两句么(windows为例):
LoadModule php5_module D:/php/php5apache2_2.dll
AddType application/x-httpd-php .php
用LoadModule来加载php5_module,把php作为apache的一个子模块来运行,这样apache才会解析php,每一次apache结束请求,都会产生一条进程来干php的活,这样的结果就是,当请求越多,服务器压力越大。
于是nginx的fast-cgi模式才会逐渐火起来。
CGI
CGI(Common Gateway Interface)既通用网关接口,只是一种通信协议,规定了服务器和应用程序之间传输数据的标准。 我们都知道tcp、知道http,那么CGI也就好理解了。所以,我们发现,CGI其实只是一个‘约定’,跟进程什么的毫无关系。
web server(比如说nginx)只是内容的分发者。比如,如果请求/index.html,那么web server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。好了,如果现在请求的是/index.php,根据配置文件,nginx知道这个不是静态文件,需要去找PHP解析器来处理,那么他会把这个请求简单处理后交给PHP解析器。Nginx会传哪些数据给PHP解析器呢?url要有吧,查询字符串也得有吧,POST数据也要有,HTTP header不能少吧,好的,CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的协议。 当web server收到/index.php这个请求后,会启动对应的CGI程序,这里就是PHP的解析器(PHP-CGI)。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程。web server再把结果返回给浏览器。
CGI模式的每次web请求都会有启动和退出过程,也就是最为人诟病的fork-and-execute模式,这样并发越大,服务器压力越高,于是nginx的fast-cgi模式才会逐渐火起来(咦,这句话我好像说过一遍了)。
PHP-CGI
上文提到了:
当web server收到/index.php这个请求后,会启动对应的CGI程序,这里就是PHP的解析器(PHP-CGI)。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程。web server再把结果返回给浏览器。
所以你可以把PHP-CGI当成是对CGI(或Fast-CGI)标准的具体实现即可。
Fast-CGI
从上文我们就一直在提Fast-CGI,从名字上就能看出,她应该是CGI的增强优化版。她也是一种通信协议,由于CGI模式运行效率比较低,就出现了FastCGI(快速通用网关接口)。
FastCGI 致力于减少网页服务器与 CGI 程序之间交互的开销,从而使服务器可以同时处理更多的网页请求。
那么她比CGI强在哪里呢?
上文说了,CGI会反复启动和退出,反复加载让CGI模式性能低下;而Fast-CGI避免了这个问题,她像是一个常驻内存(long-live)的CGI,解析php.ini、初始化执行环境,这些只进行一次,之后会弹性启动多个worker,有活就干,没活就歇着,这样就避免了重复劳动,既提高了性能,又节约了资源,这就是Fast-CGI对进程的管理。于是有一种说法,说Fast-CGI是管理CGI的,这个,仁者见仁智者见智吧,毕竟二者都只是协议。
PHP-FPM
PHP-FPM(PHP-FastCGI Process Manager)是 PHP 语言中实现了 FastCGI 协议的进程管理器,由 Andrei Nigmatulin 编写实现,已被 PHP 官方收录并集成到内核中。
从名字就可以看出,她是来管理Fast-CGI进程的,负责一个进程池,处理来自服务器的请求。PHP5.3版本之后内置于PHP中。
这里怎么去理解呢,我记得有个段子,忘记具体了,大致是这样的:
你是一个爱国的中国人(php),你要去和一个爱国的泰国人交流(服务器),但是你们互相说的语言不同,于是就约定一起写下来,翻译成英语吧(Fast-CGI协议),这个时候,你需要一个翻译机(PHP-FPM),就可以互相理解对方的话了。
当然,没有这个翻译机也行,用你现有的知识(PHP-CGI)去翻译他的话,虽然会慢,会有小错误,但不至于不能沟通。
附
参考:
http://php.net/manual/zh/install.fpm.php https://php-fpm.org/about/ https://www.zybuluo.com/phper/note/50231