做为一个phper,一直会接触到php、nignx等的相关配置,相关的名词好比PHP-FPM、CGI、Fast CGI、SAPI等等应该都或多或少接触过,但本身对于这些知识点的掌握其实相对比较分散且造成不了必定的关系,因而在网上搜了相关的文章并结合本身的一些理解,整理成此文,便于记录。php
首先,先看一个最简单的服务器请求和响应的流程html
在这个例子中,Web Server(如Nginx)只是内容的分发者,若是客户端请求的是 index.html等静态文件,那么Web Server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。nginx
若是请求的是php文件,nginx没法直接处理,就会去配置文件nginx中寻找是否有对于php文件的配置shell
server { listen 80 default_server; server_name _; index index.html index.htm index.php; root /home/wwwroot/test/public; #error_page 404 /404.html; location ~ [^/]\.php(/|$) { try_files $uri =404; fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } ...
在nginx.conf文件中,你们能够发现有这么一段配置,若是是php文件的请求,就会分发到这个逻辑中。apache
这里定义的是与php解析器进行通信的一些配置参数,其中fastcgi_pass参数约定了nginx和php进行通信的socket是unix:/tmp/php-cgi.sock,后文会讲到php同时也会对应的监听这个端口浏览器
PS:部分配置文件中这个地址会是一个IP+端口号的TCP形式,TCP能够跨服务器,而UNIX Domain Socket不通过网络层,只能用于Nginx跟PHP-FPM都在同一服务器的场景
这样子友谊的小桥就这样顺利的搭建起来了。如今小桥搭建好了,剩下的就是通信的数据格式的统一了,这时候须要用到Fast-cgi协议,这个协议约定了这二者通信的数据格式服务器
CGI:是 Web Server 与 Web Application 之间数据交换的一种协议,由于其每次请求都要执行fork-and-execut的流程,因此存在较大的性能瓶颈,如今已经不多使用FastCGI:同 CGI,是一种通讯协议,但比 CGI 在效率上作了一些优化,采用了常驻(long-live)型来减小系统的开销,使得性能大大提高网络
前面说过Fast CGI只是一种协议(看到有很多文章会将这是一个应用程序,实际上是不对的),那遵循这个协议的实现者就是咱们熟悉的PHP-FPM(FastCGI Process Manager),它的架构是由一个manager进程负责管理一个进程池,进程池中就是子进程php-cgi架构
打开php安装目录下的php-fpm.conf,能够看到有如下一段参数配置socket
listen = /tmp/php-cgi.sock listen.backlog = -1 listen.allowed_clients = 127.0.0.1 listen.owner = www
能够看到php-fpm下一样监听了/tmp/php-cgi.sock这个socket,这和前面nginx.conf的配置是对应的
因而请求最后就交由到FastCGI子进程来进行处理,FastCGI子进程完成处理后,将标准输出和错误信息从同一链接返回Web Server进行输出
因此一个php请求的自上而下的流程以下图:
这里有一个名词放在文末将可能会更加的便于理解,你们能够看到我在图中将CGI包含在一个叫SAPI的类型下,那什么是SAPI呢?下面的解释引用至鸟哥的博客
SAPI: Server abstraction API,研究过PHP架构的同窗应该知道这个东东的重要性,它提供了一个接口,使得PHP能够和其余应用进行交互数据
前面咱们讲过的Fast CGI,还有其余好比shell的CLI,以及apache的mod_php5,都属于SAPI的范畴,目的是为了让各个服务器抽象层之间遵照着相同的约定,使php自己和上层应用解耦隔离,使php的可移植性更强。
参考文章:
深刻理解Zend SAPIs(Zend SAPI Internals)
CGI、FastCGI和PHP-FPM关系图解
你肯定你真的懂Nginx与PHP的交互?