网上有很多关于如何配置Nginx+FPM的文章,但更多的是从操作的角度,告诉我们怎么做,而不是为什么要这样做。本文从NginxFPM的工作机制入手,探讨配置背后的原理,让大家真正理解Nginx和PHP是如何协同工作的。要说Nginx和PHP是如何协同工作的,就必须先说说CGI(CommonGatewayInterface)和FastCGI这两个协议。CGI是WebServer与后台语言交互的一种协议。有了这个协议,开发者可以使用任何语言来处理WebServer发送的请求并动态生成内容。但是CGI有一个致命的缺点,就是每处理一个请求都需要fork一个新的进程。随着Web的兴起,高并发已经越来越常态,这样低效的方式显然不能满足需求。就这样,FastCGI诞生了,CGI也很快退出了历史舞台。FastCGI,顾名思义,是一种速度更快的CGI,它允许在一个进程中处理多个请求,而不是一个请求处理完就直接结束进程,其性能得到了极大的提升。至于FPM(FastCGIProcessManager),它是FastCGI的实现,任何实现了FastCGI协议的WebServer都可以与之通信。与标准的FastCGI相比,FPM还提供了一些增强的功能。具体可以参考官方文档:PHP:FPMInstallation。FPM是一个PHP进程管理器,包括master进程和worker进程两个进程:master进程只有一个,负责监听端口和接收来自WebServer的请求,而worker进程一般有多个(具体数量为根据实际需要配置),每个进程都嵌入了一个PHP解释器,也就是PHP代码真正执行的地方。下图是我本机的fpm进程,1个master进程,3个worker进程:当从FPM收到一个请求,去处理后,具体流程如下:FPM的master进程收到请求,分配特定的工作进程根据配置处理请求。如果没有可用的进程,则返回错误。这就是为什么我们经常遇到Nginx502错误的原因。工作进程处理请求。如果超时,它将返回504错误。请求处理完成,返回结果为FPM接收处理请求的过程。那么Nginx是如何将请求发送给fpm的呢?这就需要从Nginx的层面来解释了。我们知道Nginx不仅是一个web服务器,还是一个强大的代理服务器。除了代理http请求外,它还可以代理很多其他的协议请求,包括本文中fpm相关的fastcgi协议。为了让Nginx能够理解fastcgi协议,Nginx提供了fastcgi模块,将http请求映射到对应的fastcgi请求。Nginx的fastcgi模块提供了fastcgi_param命令,主要处理这些映射关系。下面是Ubuntu下Nginx的一个配置文件。它的主要工作是将Nginx中的变量翻译成PHP可以理解的变量。另外,非常重要的是fastcgi_pass指令,用来指定fpm进程监听的地址。Nginx会将所有的php请求翻译成fastcgi请求,然后发送到这个地址。下面是一个简单的工作Nginx配置文件:在这个配置文件中,我们新建一个虚拟主机,监听80端口,web根目录为/home/rf/projects/wordpress。然后我们把所有以.php结尾的请求通过location指令交给fastcgi模块,这样所有的php请求都交给fpm处理,这样就完成了从Nginx到fpm的闭环。这样Nginx和FPM通信的整个过程应该就比较清楚了。文章转载自:https://segmentfault.com/a/11...
