深入理解-CLI与PHP-FPM
<p>原文地址:https://blog.csdn.net/lzx_victory/article/details/85917161</p><p>PHP-FPM模式相对于CLI比较复杂,因为PHP-FPM为常驻进程不断处理请求,因此二者只是在执行流程略有不同.</p>
<p>PHP-FPM<br>现在PHP广泛被使用的一种模式,用于解析FastCGI协议,执行相应的请求.</p>
<p>PHP-FPM 三种模式<br>static<br>FPM启动根据pm.max_children固定的woker进程数.</p>
<p>dynamic<br>FPM是启动的woker进程是变化:根据参数pm.start_servers~pm.max_children之间的.<br>pm.min_spare_servers~pm.min_spare_servers指明可空闲进程的个数,空闲进程数超过pm.min_spare_servers就会被kill掉.</p>
<p>ondemand<br>启动时不分配Woker进程,根据pm.process_idle_timeout空闲时间后会把进程kil掉.也受到pm.max_children的限制.</p>
<p>其余参数设置</p>
<div class="cnblogs_code">
<pre>pm.max_requests = 1000
<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.</span>
pm.status_path = /<span style="color: rgba(0, 0, 0, 1)">status
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">FPM状态页面的网址. 如果没有设置, 则无法访问状态页面. 默认值: none. munin监控会使用到</span>
<span style="color: rgba(0, 0, 0, 1)">
rlimit_files </span>= 1024
<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置文件打开描述符的rlimit限制. 默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。</span></pre>
</div>
<p>Frok流程<br>当PHP-FPM启动后calling process会fork master进程,然后Fork worker.</p>
<p>Worker: 实际处理请求的进程.<br>Master: 管理worker进程,对worker进程重启,关闭等操作.</p>
<p><img src="https://img2018.cnblogs.com/blog/1044910/201905/1044910-20190527143135804-969511628.png"></p>
<p><br>Master进程<br>Master通过监听"外部信号"与Woker进程的信号(SIGHLD:Woker进程发送信号,Master进程处理善后工作,然后在按照模式启动),对相应的信号来管理Worker进程.<br>信号机制:Master采用了socketpair一端写入信号事件,另一端在注册到事件机制中,在Master Loop读取事件,调用回调函数(fpm_got_signal)执行对应的信号.<br>FPM内部对事件进行了封装,用于支持不同的事件模型,例如epoll,select,kqueue等.<br>Master进程还有重要的作用统计所有Worker进程的信息,用于统计的数据结构叫做计分板.</p>
<p>Woker进程<br>Woker进程,特殊处理的信号只有SIGQUIT,其余的都是执行默认信号处理(SIG_DFL).<br>当收到SIGQUIT时,in_shutdown静态全局变量置为1,确保在fcgi_accept_request方法返回-1,不在accept新的请求并结束相应的Woker进程.<br>每个Woker进程存在于一个进程池内,根据FPM可以配置多个进程池.<br>每个Worker进程进行accept时会阻塞并接收一个请求.每个Woker进程执行accept函数在Linux2.6内核版本不会形成惊群效应.</p>
<p>FCGI协议<br>FCGI是一种交互式协议,基于CGI协议的一种变体.在每次请求到达是不需要新建进程,减少了进程创建以及销毁的资源损耗.<br>每次FastCGI请求成为Record由以下结构组成:</p>
<p>BeginRequestRecord:包含请求的信息,请求ID,以及请求的角色等.<br>EndRequestBody:请求结束的标识,包含最终Appliancation返回处理状态.<br>Header:被包含EndRequestBody,BeginRequestRecord,以及以及类型当中.每个数据段需要由Header指定这个段的类型,RequestID以及长度…</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
* Values for type component of FCGI_Header
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_BEGIN_REQUEST 1</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_ABORT_REQUEST 2</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_END_REQUEST 3</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_PARAMS 4//key value 类型.</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_STDIN 5</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_STDOUT 6</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_STDERR 7</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_DATA 8</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_GET_VALUES 9</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_GET_VALUES_RESULT10</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_UNKNOWN_TYPE 11</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)">define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE)</span>
<span style="color: rgba(0, 0, 0, 1)">typedef struct {
unsigned char version;
unsigned char type;
unsigned char requestIdB1;
unsigned char requestIdB0;
unsigned char contentLengthB1;
unsigned char contentLengthB0;
unsigned char paddingLength;
unsigned char reserved;
} FCGI_Header;</span></pre>
</div>
<p>FCGI协议详述,这里有详细的介绍以及示例.</p>
<h2>CLI 与 PHP-FPM执行流程</h2>
<h3>PHP-FPM</h3>
<p><img src="https://img2018.cnblogs.com/blog/1044910/201905/1044910-20190527143225257-1422763977.png"></p>
<p> </p>
<h3>CLI</h3>
<p>CLI也是最常用的一种模式,我们来看下他执行的过程.</p>
<p><img src="https://img2018.cnblogs.com/blog/1044910/201905/1044910-20190527143239520-1794666676.png"></p>
<p> </p>
<p><br>1.php_module_start_up:将sapi_globals中的成员变量进行初始化.<br>2.php_request_start_up:将zend引擎的编译器,扫描器,编译器等进行初始化.<br>3.php_excute_script:读取代码并扫描词法和语法生成AST,初始化op_array并将AST编译生成opcode,设置op_array对应的handler,然后执行opcode.<br>4.php_request_shutdown:调用各模块的析构函数,输出缓冲区调用扩展的RSHUTDOWN函数.销毁全局变量,关闭解析器.<br>5.php_module_shutdown:在php_module_startup初始化的内容要进行销毁.</p>
</div>
<div id="MySignature" role="contentinfo">
纵然世间炎凉百态!我自依旧初心不改!!<br><br>
来源:https://www.cnblogs.com/phpk/p/10930558.html
頁:
[1]