CGI - php-cgi - Fastcgi - php-fpm - nginx的关系

CGI:

CGI 的英文是(COMMON GATEWAY INTERFACE)公共网关接口,它的作用就是帮助服务器与语言通信,这里就是 nginx 和 php 进行通信,因为 nginx 和 php 的语言不通,因此需要一个沟通转换的过程,而 CGI 就是这个沟通的协议。

nginx 服务器在接受到浏览器传递过来的数据后,如果请求的是静态的页面或者图片等无需动态处理的则会直接根据请求的 url 找到其位置然后返回给浏览器,这里无需 php 参与,但是如果是一个动态的页面请求,这个时候 nginx 就必须与 php 通信,这个时候就会需要用到 cgi 协议,将请求数据转换成 php 能理解的信息,然后 php 根据这些信息返回的信息也要通过 cgi 协议转换成 nginx 可以理解的信息,最后 nginx 接到这些信息再返回给浏览器。

fast-cgi:

传统的 cgi 协议在每次连接请求时,会开启一个进程进行处理,处理完毕会关闭该进程,因此下次连接,又要再次开启一个进程进行处理,因此有多少个连接就有多少个 cgi 进程,这也就是为什么传统的 cgi 会显得缓慢的原因,因此过多的进程会消耗资源和内存。

而 fast-cgi 则是一个进程可以处理多个请求,和上面的 cgi 协议完全不一样,cgi 是一个进程只能处理一个请求,这样就会导致大量的 cgi 程序,因此会给服务器带来负担。

php-cgi:

php-cgi 是 php 提供给 web serve 也就是 http 前端服务器的 cgi 协议接口程序,当每次接到 http 前端服务器的请求都会开启一个 php-cgi 进程进行处理,而且开启的 php-cgi 的过程中会先要重载配置,数据结构以及初始化运行环境,如果更新了 php 配置,那么就需要重启 php-cgi 才能生效,例如 phpstudy 就是这种情况。

php-fpm:

php-fpm 是 php 提供给 web serve 也就是 http 前端服务器的 fastcgi 协议接口程序,它不会像 php-cgi 一样每次连接都会重新开启一个进程,处理完请求又关闭这个进程,而是允许一个进程对多个连接进行处理,而不会立即关闭这个进程,而是会接着处理下一个连接。它可以说是 php-cgi 的一个管理程序,是对 php-cgi 的改进。

php-fpm 会开启多个 php-cgi 程序,并且 php-fpm 常驻内存,每次 web serve 服务器发送连接过来的时候,php-fpm 将连接信息分配给下面其中的一个子程序 php-cgi 进行处理,处理完毕这个 php-cgi 并不会关闭,而是继续等待下一个连接,这也是 fast-cgi 加速的原理,但是由于 php-fpm 是多进程的,而一个 php-cgi 基本消耗 7-25M 内存,因此如果连接过多就会导致内存消耗过大,引发一些问题,例如 nginx 里的 502 错误。

同时 php-fpm 还附带一些其他的功能:

例如平滑过渡配置更改,普通的 php-cgi 在每次更改配置后,需要重新启动才能初始化新的配置,而 php-fpm 是不需要,php-fpm 分将新的连接发送给新的子程序 php-cgi,这个时候加载的是新的配置,而原先正在运行的 php-cgi 还是使用的原先的配置,等到这个连接后下一次连接的时候会使用新的配置初始化,这就是平滑过渡。