**1、CGI**:指的是Web服务器与web应用程序之间的一种数据交换协议。 **2、FastCGI**:类似于CGI,Fast-CGI也是一种通信协议,但是它在CGI的基础上, 在效率上做了一些优化。 **3、PHP-CGI**:PHP-CGI是PHP对Web服务器提供的CGI协议的接口程序,即实现了CGI协议的php解释器程序。它能解析PHP,也能通过CGI与web服务器通信。 **4、PHP-FPM**:是PHP对Web服务器提供的FastCGI协议的接口程序,即在实现解释PHP脚本和与web服务器通讯的基础上,额外还提供了相对 进程调度、任务管理功能。 ### **PHP-FPM运行模式** >我们先聊聊传统 PHP-FPM 架构的运作模式,PHP-FPM 是一个多进程的 FastCGI 管理程序,是绝大多数 PHP 应用所使用的运行模式。 > 假设我们使用 Nginx 提供 HTTP 服务(Apache 同理),所有客户端发起的请求最先抵达的都是 Nginx,然后 Nginx 通过 FastCGI 协议将请求转发给 PHP-FPM 处理。 > PHP-FPM 的 Master进程 会为每个请求分配一个 Worker进程 来处理,这个处理指的就是,等待 PHP 脚本的解析,等待业务处理的结果返回,完成后回收子进程,这整个的过程是阻塞等待的,也就意味着 PHP-FPM 的进程数有多少能处理的请求也就是多少。 > 假设 PHP-FPM 有 200 个 Worker进程,一个请求将耗费 1 秒的时间,那么简单的来说整个服务器理论上最多可以处理的请求也就是 200 个,QPS 即为 200/s。 > 在高并发的场景下,这样的性能往往是不够的,尽管可以利用 Nginx 作为负载均衡配合多台 PHP-FPM 服务器来提供服务,但由于 PHP-FPM 的阻塞等待的工作模型,一个请求会占用至少一个 MySQL 连接,多节点高并发下会产生大量的 MySQL 连接,而 MySQL 的最大连接数默认值为 100,尽管可以修改,但显而易见该模式没法很好的应对高并发的场景。 **CGI即通用网关接口,是 Web 服务器调用外部程序时所使用的一种服务端应用的规范。** >早期的 Web 通信请求的都是静态数据,比如图片、Html文档等,随着Web的发展,静态网站已经不能满足人们的需要,所以引入 CGI 以便客户端请求能够触发 Web 服务器运行另一个外部程序,客户端所输入的数据也会传给这个外部程序,该程序运行结束后会将生成的 HTML 和其他数据通过 Web 服务器再返回给客户端,利用 CGI 可以针对用户请求动态返回给客户端各种各样动态变化的信息。 **FastCGI是 CGI 的升级版本,** >为了提升 CGI 的性能而生,CGI 针对每个 HTTP 请求都会 `fork` 一个新进程来进行处理(解析配置文件、初始化执行环境、处理请求),然后把这个进程处理完的结果通过 Web 服务器转发给用户,刚刚 `fork` 的新进程也随之退出,如果下次用户再请求动态资源,那么 Web 服务器又再次 `fork` 一个新进程,如此周而复始循环往复。而 FastCGI 则会先 `fork` 一个 `master` 进程,解析配置文件,初始化执行环境,然后再 `fork` 多个 `worker` 进程(与 Nginx 有点像),当 HTTP 请求过来时,`master` 进程将其会传递给一个 `worker` 进程,然后立即可以接受下一个请求,这样就避免了重复的初始化操作,效率自然也就提高了。而且当 `worker` 进程不够用时,`master` 进程还可以根据配置预先启动几个 `worker` 进程等着;当空闲 `worker` 进程太多时,也会关掉一些,这样不仅提高了性能,还节约了系统资源。 **PHP-FPM** >这样一来,PHP-FPM 就好理解了,FastCGI 只是一个协议规范,需要每个语言具体去实现,PHP-FPM 就是 PHP 版本的 FastCGI 协议实现,有了它,就是实现 PHP 脚本与 Web 服务器(通常是 Nginx)之间的通信,同时它也是一个 PHP SAPI,从而构建起 PHP 解释器与 Web 服务器之间的桥梁。 PHP-FPM 负责管理一个进程池来处理来自 Web 服务器的 HTTP 动态请求,在 PHP-FPM 中,`master` 进程负责与 Web 服务器进行通信,接收 HTTP 请求,再将请求转发给 `worker` 进程进行处理,`worker` 进程主要负责动态执行 PHP 代码,处理完成后,将处理结果返回给 Web 服务器,再由 Web 服务器将结果发送给客户端。这就是 PHP-FPM 的基本工作原理