Nginx 与 PHP-FPM 的协作机制

作为现在被很多大公司采用的Nginx + PHP-FPM,它们是怎么样做到协同合作呢?

FastCGI 协议

要搞明白这个问题,首先得说 CGI (Common Gateway Interface) 和 FastCGI 这两个协议。

CGI 是 Web Server 与后台语言交互的协议,有了这个协议,开发者可以使用任何语言处理 Web Server 发来的请求,动态的生成内容。但 CGI 有一个致命的缺点,那就是每处理一个请求都需要 fork 一个全新的进程,并且重新启动脚本解析器来执行解析,随着 Web 的兴起,高并发越来越成为常态,这样低效的方式明显不能满足需求。就这样,FastCGI 诞生了,CGI 很快就退出了历史的舞台。FastCGI,顾名思义为更快的 CGI,它允许在一个进程内处理多个请求,而不是一个请求处理完毕就直接结束进程,性能上有了很大的提高。

PHP-FPM

至于 FPM (FastCGI Process Manager),它是 FastCGI 的实现,任何实现了 FastCGI 协议的 Web Server 都能够与之通信。FPM 之于标准的 FastCGI,也提供了一些增强功能。

FastCGI进程管理器php-fpm自身初始化,启动主进程 master 和启动start_servers(配置项) 个 worker子进程。主进程主要是监听9000端口,同时管理着子进程,子进程等待来自Web Server的连接。 每个进程内部都有一个 PHP 解释器,是 PHP 代码真正执行的地方。

从 FPM 接收到请求,到处理完毕,其具体的流程如下:

1、FPM 的 master 进程接收到请求
2、master 进程根据配置指派特定的 worker 进程进行请求处理,如果没有可用进程,返回错误,这也是我们配合 Nginx 遇到502错误比较多的原因。
3、worker 进程处理请求,如果超时,返回504错误
4、请求处理结束,返回结果

更多介绍:http://blog.csdn.net/STFPHP/article/details/52922371

FPM 从接收、处理到返回的整个流程已经清楚了,那么 Nginx 又是如何发送请求给 fpm 的呢?这就需要从 Nginx 层面来说明了。

Nginx

Nginx是一款轻量级的 Web服务器、反向代理服务器以及电子邮件(IMAP/POP3)代理服务器。

Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块:

1、核心模块:HTTP模块、EVENT模块和MAIL模块
2、基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块,
3、第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。

Nginx的模块从功能上分为如下三类:

1、Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
2、Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。
3、Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。 

Nginx本身做的工作实际很少,当它接到一个HTTP请求时,它仅仅是通过查找配置文件将此次请求映射到一个location block,而此location中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做Nginx真正的劳动工作者。通常一个 location 中的指令会涉及一个handler模块和多个filter模块(当然,多个location可以复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理。

Nginx 与 PHP-FPM 的协作机制_第1张图片

上图是Nginx的架构,这个架构类似于Apache的Worker工作状态。

所有实际上的业务处理逻辑都在worker进程。worker进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个nginx服务被停止。Worker中这个函数执行内容如下:

1、操作系统提供的机制(例如epoll, kqueue等)产生相关的事件。
2、接收和处理这些事件,如是接受到数据,则产生更高层的request对 象。
3、处理request的header和body。
4、产生响应,并发送回客户端。
5、完成request的处理。
6、重新初始化定时器及其他事件。 

Nginx 与 PHP-FPM如何协作:

Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。

当客户端请求到达Web Server Nginx时,Nginx通过location指令,将所有以php为后缀的文件都交给 PHP-FPM来处理,从而完成 Nginx 到 fpm 的闭环。

这里,Nginx 可以通过 TCP/IP连接 PHP-FPM,也可以通过 UNIX与套接字来连接 PHP-FPM。然后将CGI环境变量和标准输入发送给 PHP-FPM。

检测到来自 Nginx 的请求后,PHP-FPM主进程选择并连接到一个子进程,并由该子进程来接收这次请求。

PHP-FPM子进程完成处理后将标准输出和错误信息从同一连接返回 Nginx。当 PHP-FPM子进程关闭连接时,请求便处理完成。

PHP-FPM子进程接着等待并处理由主进程分配的下一个连接。

你可能感兴趣的:(Nginx)