一、CGI(COMMON GATEWAY INTERFACE) 公共网关接口
它的作用就是帮助服务器与语言通信,这里就是nginx和php进行通信,因为nginx和php语言不通,因此需要一个沟通转换的过程,而CGI就是这个沟通的协议。
CGI是Web服务器和一个独立的进程之间的协议,它会把HTTP请求Request的Header头设置成进程的环境变量,HTTP请求的Body正文设置成进程的标准输入,进程的标准输出设置为HTTP响应Response,包含Header头和Body正文。
nginx服务器在接受到浏览器传递过来的数据后,如果请求的是静态的页面或者图片等无需动态处理的则会直接根据请求的URL找到其位置后返回给浏览器,这里无需php参与, 但是如果是一个动态的页面请求,这个时候nginx就必须与php通信,这个时候就会需要用到cgi协议,将请求数据转换成php能理解的信息,然后php根据这些信息返回的信息也要通过cgi协议转换成nginx可以理解的信息,最后nginx接到这些信息再返回给浏览器
二、FastCGI:是Web服务器与处理程序之间通信的一种协议,是CGI的改进版本。
传统的cgi协议在每次连接请求时,会开启一个进程进行处理,处理完毕会关闭该进程,因此下次连接,又要再次开启一个进程进行处理,因此有多少个连接就有多少个cgi进程,这也就是为什么传统的cgi会显得缓慢的原因,因此过多的进程会消耗资源和内存。
而fast-cgi则是一个进程可以处理多个请求,和上面的cgi协议完全不一样,cgi是一个进程只能处理一个请求,这样就会导致大量的cgi程序,因此会给服务器带来负担。
三、PHP-CGI: 是php提供给web serve也就是http前端服务器的cgi协议 接口程序,当每次接到http前端服务器的请求都会开启一个PHP-CGI进程进行处理,而且开启的PHP-CGI的过程中会先要重载配置,数据结构以及初始化运行环境,如果更新了PHP配置,那么就需要重启PHP-CGI才能生效,例如phpstudy就是这种情况。
CGI是一个协议,PHP语言对CGI接口规范的实现也就是PHP-CGI,也就是PHP的解释器。随着技术的发展,PHP-CGI的性能问题逐渐暴露,不是那么尽如人意。PHP在运行的时候是依赖配置文件php.ini
的,所以每当PHP-CGI开始工作的时候,它完全是一个新进程,需要重新加载PHP配置文件并初始化,这就造成了很大的资源和时间的浪费。
每当客户端请求CGI时,Web服务器就会请求操作系统生成一个新的CGI解释器进程php-cgi.exe
,CGI的一个进程处理完一个请求后退出,下一个请求来时在先操作系统申请创建新进程。在访问量较少没有并发的情况下这样做是没有问题的,一旦出现访问量增大,并发出现时这种方式就不再合适了,于是便出现了FastCGI。
php-fpm:
php-fpm是php提供给web serve也就是http前端服务器的fastcgi协议接口程序,它不会像php-cgi一样每次连接都会重新开启一个进程,处理完请求又关闭这个进程,而是允许一个进程对多个连接进行处理,而不会立即关闭这个进程,而是会接着处理下一个连接。它可以说是php-cgi的一个管理程序,是对php-cgi的改进。
FastCGI是一个协议,PHP-FPM实现了这个协议。FastCGI是CGI的改进版,它是一个常驻内存的CGI服务。常用的PHP-FPM就是在这种模式下运行的,PHP-FPM负责Fork多个进程,每个进程都运行着PHP解释器。
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还是使用的原先的配置,等到这个连接后下一次连接的时候会使用新的配置初始化,这就是平滑过渡。
可能上面文字叙述很难理解,下面用图形来简要的说明浏览器请求web服务器的过程、cgi以及fastcgi,以及php-cgi和php-fpm之间的区别和联系:
上面是使用php-fpm的动态页面的过程,下面补充没有普通cgi协议的情况;
这里的web server可以是nginx,也可以是IIS和apache等http服务器,也可以成为网站服务器或者前端服务器。
PHP的解释器PHP-CGI只是一个CGI程序,它本身只能解析请求并返回结果,不会对进程进行管理,所以就出现了一些能够调度PHP-CGI进程的程序。PHP-FPM是PHP对FastCGI的一种具体实现,是fast-cgi进程管理工具。PHP-FPM启动后会创建多个CGI子进程,然后主进程负责管理子进程,同时对外提供一个socket,那么Web服务器当要转发一个动态请求时,只需要按照FastCGI协议要求的格式将数据发往socket即可。PHP-FPM创建的子进程去争夺socket连接,谁抢到谁处理并将结果返回给Web服务器。当其中一个子进程异常退出时,PHP-FPM主进程会去监控,一旦发现CGI子进程就会又启动一个。