搞清楚php-cli php-cgi php-fpm fastcgi 之间的关系

2021-12-24 18:44:22 浏览数 (1)

阅读量: 37

首先,我们从客户端的请求开始,一个客户端发送http请求过来经过了哪些步骤

  1. http请求域名解析–>发送包到服务器…
  2. 服务器收到请求
  3. 若是html的(静态资源)直接返回,若是.php结尾的文件,nginx就要经过fastcgi协议,再到php-fpm处理请求,php-fpm再通过fastcgi协议返回再到nginx再返回非客户端

php-cli(Command Line Interface 命令行接口)

php-cli在命令行下面直接运行php,这个时候php的生命周期也就是脚本结束了,php的生命周期也就over了。

目前,CLI模式下执行php脚本的情况比较少,究其原因是无法满足复杂的业务需要,也不能传递post参数、上传文件,ui交互较差,更适合开发人员使用。

php-cgi(Common Gateway Interface 公共网关接口)

php-cgi就是一个协议(与http一样),是一种与语言无关的协议,规定传输哪些数据、以什么样的格式传递给后方处理的一个协议,然后php就会启动解析器,初始化环境,然后处理请求,退出程序。

php-cgi的工作流程如下:

上附图中内容可能部分不够准确,但大致流程是没问题的,看出cgi每次都会解析,初始化,执行,退出。

只不过,CGI模式也称为fork-execute-kill 模式:每当有一个请求过来时,Web Server都会启动一个php-cgi去处理这个请求,请求处理完成之后这个php-cgi就会自动销毁。对于QPS较小的情况下,CGI模式还好,但对于成百上千的QPS,这个时候的平响就会很长。为什么这么说呢?因为Web Server每创建一个php-cgi都是要给其分配内存和其他资源的,QPS较大时就会造成内存以及其他资源的紧张,最终造成整个平响的超长。

有一点要注意:CGI模式下,php-cgi的启动是受Web Server控制的。

对于目前很多高并发的网站而言,CGI模式很显眼不能满足他们的需求,那有没有什么办法解决一下呢?

回想一下上面php-cgi的产生、销毁过程:请求达到Web Server → 生成php-cgi进程 → 请求转发给php-cgi→php-cgi处理请求 → 返回给Web Server处理结果 → php-cgi 销毁。有没有一种方法可以实现php-cgi预生成(可能不够准确)、常驻内存呢?答案是肯定的,这也就是我们下面要说的fastcgi模式。

fastcgi也会跟php-fpm一样,先启动一个master和多个worker,这样是不是就更好了,不用每次都初始化,执行,退出了,这个协议也就更加优美

fastcgi

fastcgi也是一种协议,PHP语言的实现方式为php-cgi。fastcgi是cgi的升级版,既然是升级版,那较cgi又提升了哪些功能呢?

提升点就是php-cgi预生成与常驻内存。对于这两点大家可能不理解,解释一下。

预生成:在请求到达php-cgi之前就生成一定数量的php-cgi。

常驻内存:php-cgi在处理过一个请求之后并不会销毁,它会一直存在,等待着php-fpm分配的下一个请求。

OK,上面也说了,预生成php-cgi的时候会生成一定的数量。这些php-cgi在Web Server的某个请求转发过来之后都能对该请求进行处理,如果每个php-cgi都尝试进行处理就会造成”惊群效应“。那到底哪个能处理呢?很显然,我们需要对这些个php-cgi进行一个进程调度,php-fpm出现了。

php-fpm

前面说了,php-fpm是php-cgi的进程管理器。

这里有一点要注意,CGI协议时,php-cgi的启动是受Web Server控制的;fastcgi协议时,php-cgi的启动跟Web Server没有任何关系了,它只受php-fpm的调度。而且,这个时候Web Server转发请求以及传递参数给某个php-cgi都需先经过php-fpm的调度,之后再由php-fpm控制这个请求具体交给那个php-cgi处理。

可以将php-fpm独立运行在非web服务器上,实现所谓的动静分离。

盗用别人的一张图,下面是fasgcgi接口协议下一个客户端请求响应的完整过程。

0 人点赞