最近在研究PHP的源码,有时候会延伸到很多东西。这里就专程找了下php-fpm的内容学习下。
是什么?
在理解php-fpm之前,我们要先搞清楚几个关键词以及他们之间的关系:CGI
FastCGI
php-fpm
php-cgi.
CGI:(Common Gateway Interface),即通用网关接口的意思,描述的是服务器和请求处理程序之间传输数据的一种标准。 所以,CGI是一种协议。CGI可用于任何语言,只要该语言具有标准的输出、输入以及环境变量。如perl、php等语言。 以nginx和php为例,我们可以理解为,这是php在与nginx服务器之间交互时,对传输数据的一种约定。
在《HTTP权威指南》书中,是这么描述的
CGI是一个标准接口集,Web 服务器可以用它来装载程序以响应对特定 URL 的 HTTP 请求,并收集程序的输出数据,将其放在 HTTP 响应中回送。
那CGI的原理是什么呢
当需要请求使用网关的资源时,服务器会请辅助应用程序来处理请求(比如nginx会请php程序来处理请求)。 服务器会将辅助应用程序的数据传送给网关。然后网关会向服务器返回一条响应或者响应数据,服务器再将响应或响应数据转发给客户端。
由此我们可以清楚两点:
服务器和网关是相互独立的应用程序
服务器是应用程序和网关之间的一座桥梁
具体原理如图所示:
image.png
由此,我们可知CGI有一个致命的弱点,即应用程序的每次请求,都要引发一个全新的进程。所以,服务器和网关之间的分离会造成性能的 耗费,会限制使用CGI的服务器的性能,并且会加重服务端机器资源的负担。
好啦,重角要登场了。后来为了解决这个问题,出现了FastCGI,也就是快速的CGI。 接下来,我们再详细的了解下FastCGI。
FastCGI:(Fast Common Gateway Interface),即快速通用网关接口,是一种让交互程序与Web服务器通信的协议。它是CGI的增强版本
FastCGI致力于减少网页服务器与CGI程序之间互动的开销,从而使服务器可以同时处理更多的网页请求。
以上来自维基百科,我们可以由此了解到,FastCGI,同CGI一样,也是一种协议,只不过它是CGI的增强版本。
那FastCGI是如何增强性能的呢?
FastCGI接口模拟了CGI,但FastCGI是作为持久守护进程运行的,消除了为每个请求建立或拆除新进程所带来的性能损耗。也就是允许,一个进程内可以处理多个请求。 也就说CGI解释器保持在内存中,并接受了FastCGI进程管理和调度,所以它可以提供更好的性能,可扩展性,故障切换等特点
FastCGI的特点
FastCGI与语言无关
FastCGI应用在进程中,独立于核心网络服务器,提供了一个比API环境更安全的环境。 APIs的代码和web服务器的应用的核心是 紧紧关联的。这也就意味着在API应用程序的错误可能会损坏其它应用程序或核心服务器。恶意API应用程序代码甚至可以窃取另一个应用程序或核心服务器密钥。
FastCGI技术摸钱支持PHP,C/C++, Java language, Perl, Tcl, Python, SmallTalk, Ruby etc.. 它在Apache, ISS, Lighttpd和其他流行的 服务器中的相关模块都是可以使用的。FastCGI不依赖于任何服务器体系结构,所以即使服务器在技术上改变了,FastCGI还是稳定的
FastCGI的工作原理
Web Server 启动时载入FastCGI进程管理器 (IIS ISAPI 或Apache Module)
FastCGI进程管理器首先初始化自己,启动一批CGI解释器进程(可见多个php-cgi),然后等待来自Web Server的连接。
当Web Server中的一个客户端请求达到时, FastCGI进程管理器会选择并连接一个CGI解释器。Web server的CGI环境变量和标准输入会被送达FastCGI进程的php-cgi。
FastCGI子进程从同一连接完成返还给Web Server的标准输出和错误信息。当请求进程完成后,FastCGI进程会关闭此连接。FastCGI会等待并出来来自FastCGI进程管理器(运行在Web Server中的)的下一个连接。 在CGI模式,php-cgi然后会退出。
FastCGI的不足
因为是多进程,所以比CGI多线程消耗更多的服务器内存,PHP-CGI解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数。 Nginx 0.8.46+PHP 5.2.14(FastCGI)服务器在3万并发连接下,开启的10个Nginx进程消耗150M内存(15M10=150M),开启的64个php-cgi进程消耗1280M内存(20M64=1280M),加上系统自身消耗的内存,总共消耗不到2GB内存。 如果服务器内存较小,完全可以只开启25个php-cgi进程,这样php-cgi消耗的总内存数才500M。
PHP-CGI: PHP-CGI是PHP自带的FastCGI管理器。
PHP-CGI的不足
php-cgi变更php.ini配置后需重启php-cgi才能让新的php-ini生效,不可以平滑重启
直接杀死php-cgi进程,php就不能运行了。(PHP-FPM和Spawn-FCGI就没有这个问题,守护进程会平滑从新生成新的子进程。)
php-fpm
PHP-FPM是一个PHP FastCGI管理器,是只用于PHP的,可以在
PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。
现在我们可以在最新的PHP 5.3.2的源码树里下载得到直接整合了PHP-FPM的分支,据说下个版本会融合进PHP的主分支去。相对Spawn-FCGI,PHP-FPM在CPU和内存方面的控制都更胜一筹,而且前者很容易崩溃,必须用crontab进行监控,而PHP-FPM则没有这种烦恼。 PHP5.3.3已经集成php-fpm了,不再是第三方的包了。PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多有点,所以被PHP官方收录了。在./configure的时候带 –enable-fpm参数即可开启PHP-FPM。