PHP-FPM、CGI、FastCGI的关系分析我都或多或少接触过,但是我对这些知识点的掌握其实比较零散,无法形成一定的关系,于是搜索了相关文章上网,结合自己的一些理解整理了这篇文章,方便记录。首先我们来看一个最简单的服务器请求和响应过程。在这个例子中,WebServer(比如Nginx)只是一个内容分发器。如果客户端请求的是一个静态文件,比如index.html,那么WebServer会去文件系统中找到这个文件,并发送给浏览器,浏览器中分布着静态数据。如果请求是php文件,nginx无法直接处理,会去nginx的配置文件中查找是否有php文件的配置服务器{listen80default_server;服务器名称_;indexindex.htmlindex.htmindex.php;root/home/wwwroot/test/public;#error_page404/404.html;位置~[^/]\.php(/|$){try_files$uri=404;fastcgi_passunix:/tmp/php-cgi.sock;fastcgi_index索引.php;包括fastcgi.conf;}...在nginx.conf文件中,可以找到这样的配置,如果是请求一个php文件,就会分发到这个逻辑。这里定义了一些与php解析器通信的配置参数,其中fastcgi_pass参数约定了nginx与php通信的socket为unix:/tmp/php-cgi.sock,后面也会提到与php的对应监听这个端口PS:有些配置文件中的地址会是IP+端口号的TCP形式,TCP可以跨服务器,UNIXDomainSocket不走网络层,只能用在Nginx的场景和PHP-FPM在同一台服务器上就这样顺利的架起了友谊的小桥。小桥搭好了,剩下的就是统一通信的数据格式了。这时候就需要Fast-cgi协议了。该协议规定了两个CGI之间通信的数据格式:WebServer和WebApplication之间进行数据交换的协议,由于每次请求都要执行fork-and-execut过程,所以存在较大的性能瓶颈,而FastCGI现在已经很少用了:它和CGI一样是一种通信协议,但是比CGI在效率上做了一些优化,采用了常驻(long-live)类型来减少系统的开销,这大大提高了性能。program,其实是错误的),遵循这个协议的实现者就是大家熟悉的PHP-FPM(FastCGIProcessManager),它的架构是一个manager进程,负责管理一个进程池,进程池就是php-cgi的子进程打开php安装目录下的php-fpm.conf,可以看到如下参数配置listen=/tmp/php-cgi.socklisten.backlog=-1listen.allowed_clients=127.0.0.1listen.owner=www可以看到socket/tmp/php-cgi.sock也在php-fpm下监听,对应前面的nginx.conf配置,所以请求最终交给FastCGI子进程处理。FastCGI子进程完成处理后,标准输出和错误信息从同一个连接返回给WebServer输出,所以一个php请求的自上而下的流程如下:文章的结尾,这可能更容易理解。大家可以看到我在图中IncludeCGIunderatypecalledSAPI,那么什么是SAPI呢?以下解释参考鸟哥的博客SAPI:ServerabstractionAPI。学过PHP架构的同学应该知道这玩意的重要性。它提供了一个接口,使PHP能够与其他应用程序进行交互。我们前面讲的数据FastCGI,还有其他的比如shellCLI,apache的mod_php5,都属于SAPI的范畴。更便携。参考文章:深入理解ZendSAPIs(ZendSAPIInternals)CGI、FastCGI与PHP-FPM关系图你确定你真的了解Nginx和PHP的交互吗?
