Nginx可以接收请求并转发给PHP-FPM。
1.开始深入Nginx与FastCGI协议
通过对Nginx新增Server配置实现了nginx与PHP的一次通信,配置文件非常简单。
从上图的Nginx配置中可以注意到 fastcgi* 开头的一些配置,以及引入的 fastcgi.conf 文件。其实在fastcgi.conf中,也是一堆fastcgi*的配置项,只是这些配置项相对不常变,通常单独文件保管可以在多处引用。
CGI是通用网关协议,FastCGI则是一种常住进程的CGI模式程序。
PHP-FPM的全称是PHP FastCGI Process Manager,即PHP-FPM会通过用户配置来管理一批FastCGI进程。
例如:在PHP-FPM管理下的某个FastCGI进程挂了,PHP-FPM会根据用户配置来看是否要重启补全,PHP-FPM更像是管理器,而真正衔接Nginx与PHP的则是FastCGI进程。
介绍FastCGI在请求流中的位置,如下图所示:
如上图所示,FastCGI的下游,是CGI-APP,在我们的LNMP架构里,这个CGI-APP就是PHP程序。而FastCGI的上游是Nginx,他们之间有一个通信载体,即图中的socket。fastcgi_pass也常配置为一个http接口地址。
图中的Pre-fork,则对应着我们PHP-FPM的启动,也就是在我们启动PHP-FPM时便会根据用户配置启动诸多FastCGI触发器(FastCGI Wrapper)。
fastcgi_param所声明的内容,将会被传递给“FastCGI server”,那这里指的就是fastcgi_pass所指向的server,也就是我们Nginx+PHP模式下的PHP-FPM所管理的FastCGI进程,或者说是那个socket文件载体。
有的同学会问:“为什么PHP-FPM管理的那些FastCGI进程要关心这些参数呢?”
我们做PHP应用开发时候有没有用到 $_SERVER 这个全局变量,它里面包含了很多服务器的信息,比如包含了用户的IP地址。
Nginx这个模块里fastcgi_param参数,就是考虑后端程序有时需要获取Webserver外部的变量以及服务器情况,那么ngx_http_fastcgi_module就帮我们做了这件事。
FastCGI的作用是Nginx、PHP的接口载体,就像插座与插销,让流行的WebServer与“世界上最好的语言”有了合作的可能。
譬如我在前年曾实现了Java程序中按照FastCGI Client的方式(替代Nginx)与PHP-FPM通信,实现Java项目+PHP的一种组合搭配,解决的问题是Java程序一般来说在代码调整后需要编译过程,而PHP可以随时调整代码随时生效,那么让Java作为项目外壳,一些易变的代码由PHP实现,在需要的时候Java程序通过FastCGI与PHP打交道就好。这套想法也是基于对Nginx+PHP交互模式的理解之上想到的。
Nginx+PHP的工程模式下,两位主角分工明确,Nginx负责承载HTTP请求的响应与返回,以及超时控制记录日志等HTTP相关的功能,而PHP则负责处理具体请求要做的业务逻辑,它们俩的这种合作模式也是常见的分层架构设计中的一种,在它们各有专注面的同时,FastCGI又很好的将两块衔接,保障上下游通信交互。