cgi、pfastcgi、php-cgi、php-fpm
<ul>
<li><a href="https://blog.csdn.net/qq_29677867/article/details/91445201">https://blog.csdn.net/qq_29677867/article/details/91445201</a></li>
<li><a href="https://www.jb51.net/article/159679.htm">https://www.jb51.net/article/159679.htm</a></li>
<li><a href="https://baijiahao.baidu.com/s?id=1637483210158521104&wfr=spider&for=pc">https://baijiahao.baidu.com/s?id=1637483210158521104&wfr=spider&for=pc</a></li>
<li><a href="https://blog.csdn.net/DarkAngel1228/article/details/103556312">https://blog.csdn.net/DarkAngel1228/article/details/103556312</a></li>
</ul>
<h2>CGI、fastcgi、php-cgi、php-fpm</h2>
<ul>
<li>CGI
<ul>
<li>格式化Web Server传递数据的通信协议</li>
</ul></li>
<li>fastcgi
<ul>
<li>对每次请求启动一个cgi解释器进程的优化</li>
</ul></li>
<li>php-cgi
<ul>
<li>是php的cgi协议进程解释器</li>
</ul></li>
<li>php-fpm
<ul>
<li>对fastcgi协议的实现,是进程管理器</li>
</ul></li>
</ul>
<h2>CGI</h2>
<ul>
<li>CGI 全拼 Common Gateway Interface 公共网关接口</li>
<li>默认为将 PHP 编译为 CLI 和 CGI 程序。
<ul>
<li>将建立一个命令行解释器,可用于 CGI 处理或非 web 相关的 PHP 脚本。</li>
<li>如果用户运行着一个 PHP 模块支持的 web 服务器,那通常为性能考虑应该使用模块方式。</li>
<li>CGI 版可以使 Apache 用户用不同的用户 ID 运行不同的 PHP 页面。</li>
</ul></li>
<li>CGI是为了保证Web Server传递过来的数据是标准格式的,是一种通信协议。
<ul>
<li>把用户传递过来的数据转变成一个key-value的字典,字典里还有HTTP协议的参数</li>
<li>把数据组织成一个固定结构形式的数据。方便任何符合CGI协议的程序调用</li>
<li>CGI协议用来确定webserver(如nginx),也就是内容分发服务器传递过来什么数据,什么样格式的数据。</li>
</ul></li>
</ul>
<h2>CGI工作流程</h2>
<ul>
<li>客户端请求的是 index.html,Web Server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。</li>
<li>当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器。
<ul>
<li>接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。</li>
</ul></li>
</ul>
<h2>fastcgi</h2>
<ul>
<li>Fastcgi是CGI的升级版,一种语言无关的协议,FastCGI是用来提高CGI程序性能的。</li>
<li>主要是针对每次请求过来时都需要启动一个cgi解释器进程的优化,不再需要cgi解释器进程每次收到webserver请求后都需要重新加载php.ini文件和初始化执行环境。</li>
</ul>
<h4>FastCGI"的对进程的管理</h4>
<ul>
<li>标准的CGI对每个请求都会执行上边这些步骤,所以处理每个请求的时间会比较长</li>
<li>FastCGI会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。</li>
<li>当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。</li>
<li>当worker不够用时,master可以根据配置预先启动几个worker等着;</li>
<li>当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源</li>
</ul>
<h2>php-cgi</h2>
<ul>
<li>是php的cgi协议进程解释器,每次启动时,需要经历加载php.ini文件->初始化执行环境->处理请求->返回内容给webserver->php-cgi进程退出的流程。</li>
</ul>
<h2>php-fpm</h2>
<ul>
<li>对fastcgi协议的实现,是进程管理器。</li>
<li>启动时包括master和worker进程两部分
<ul>
<li>master进程监听端口,接收来自webserver请求,worker进程一般具有多个,每个worker进程都有一个cgi进程解释器,用来执行php代码。</li>
</ul></li>
</ul>
<h2>php-fpm两种执行方式</h2>
<ul>
<li>与Apache一样,它的进程数也是可以根据设置分为动态和静态</li>
<li>一种是直接开启指定数量的php-fpm进程,不再增加或者减少</li>
<li>另一种则是开始的时候开启一定数量的php-fpm进程,当请求量变大的时候,动态的增加php-fpm进程数到上限,当空闲的时候自动释放空闲的进程数到一个下限。</li>
</ul>
<h2>php启动和工作原理</h2>
<ul>
<li>启动phpfpm时,会启动master进程,加载php.ini文件,初始化执行环境,并启动多个worker进程。每次请求来时会将请求传递给worker进程进行处理</li>
</ul>
<h2>php平滑重启原理</h2>
<ul>
<li>每次修改完php.ini配置并重启后,会启动新的worker进程加载新的配置,而之前已经存在的进程会在工作完成之后销毁,因此实现平滑重启</li>
</ul>
<h2>Nginx+FastCGI运行原理</h2>
<ul>
<li>Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。</li>
<li>FastCGI接口在Linux下是socket(这个socket可以是文件socket,也可以是ip socket)。</li>
</ul>
<h2>Nginx+PHP-FPM</h2>
<ul>
<li>PHP-FPM是管理FastCGI的一个管理器,它作为PHP的插件存在</li>
<li>Nginx通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理,而这里的IP地址和端口就是FastCGI进程监听的IP地址和端口。</li>
</ul>
<h2>Nginx 如理 HTTP 请求</h2>
<ul>
<li>Nginx 在启动时,解析配置文件,得到需要监听的端口与 IP 地址,</li>
<li>Nginx 主进程里先初始化好这个监控的Socket,再分出多个子进程出来。子进程会竞争接受新的连接。</li>
<li>
<p>客户端向 nginx 发起连接,进行三次握手,与 nginx 建立好一个连接后。</p>
</li>
<li>某一个子进程会接受成功,得到这个建立好的连接的 Socket ,</li>
<li>创建 nginx 对连接的封装,即 ngx_connection_t 结构体。</li>
<li>设置读写事件处理函数,并添加读写事件来与客户端进行数据的交换。</li>
<li>Nginx 或客户端来主动关掉连接</li>
</ul>