PHP7内核CGI与FastCGI详解


Posted in PHP onApril 14, 2019

CGI:是 Web Server 与 Web Application 之间数据交换的一种协议。
FastCGI:同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。

PHP-CGI:是 PHP (Web Application)对 Web Server 提供的 CGI 协议的接口程序。

PHP-FPM:是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能一些任务管理

CGI工作流程

1.如果客户端请求的是 index.html,那么Web Server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。

2.当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。

FastCGI工作流程

1.如果客户端请求的是 index.html,那么Web Server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。

2.当Web Server收到 index.php 这个请求后,FastCGI程序(FastCGI在启动时就初始化执行执行环境,每个CGI进程池各个CGI进程共享执行环境)在CGI进程池中选择一个CGI进程处理请求,再以规定CGI规定的格式返回处理后的结果,继续等待下一个请求。

PHP-FPM基本实现

1.PHP-FPM的实现就是创建一个master进程,在master进程中创建worker pool并让其监听socket,然后fork出多个子进程(work),这些子进程各自accept请求,子进程的处理非常简单,它在启动后阻塞在accept上,有请求到达后开始读取请求数据,读取完成后开始处理然后再返回,在这期间是不会接收其它请求的,也就是说PHP-FPM的子进程同时只能响应一个请求,只有把这个请求处理完成后才会accept下一个请求

2.PHP-FPM的master进程与worker进程之间不会直接进行通信,master通过共享内存获取worker进程的信息,比如worker进程当前状态、已处理请求数等,当master进程要杀掉一个worker进程时则通过发送信号的方式通知worker进程。

3.PHP-FPM可以同时监听多个端口,每个端口对应一个worker pool,而每个pool下对应多个worker进程

PHP7内核CGI与FastCGI详解

Worker工作流程

1.等待请求: worker进程阻塞在fcgi_accept_request()等待请求;

2.解析请求: fastcgi请求到达后被worker接收,然后开始接收并解析请求数据,直到request数据完全到达;

3.请求初始化: 执行php_request_startup(),此阶段会调用每个扩展的:PHP_RINIT_FUNCTION();

4.编译、执行: 由php_execute_script()完成PHP脚本的编译、执行;

5.关闭请求: 请求完成后执行php_request_shutdown(),此阶段会调用每个扩展的:PHP_RSHUTDOWN_FUNCTION(),然后进入步骤(1)等待下一个请求。

Master进程管理

1.static: 这种方式比较简单,在启动时master按照pm.max_children配置fork出相应数量的worker进程,即worker进程数是固定不变的

2.dynamic: 动态进程管理,首先在fpm启动时按照pm.start_servers初始化一定数量的worker,运行期间如果master发现空闲worker数低于pm.min_spare_servers配置数(表示请求比较多,worker处理不过来了)则会fork worker进程,但总的worker数不能超过pm.max_children,如果master发现空闲worker数超过了pm.max_spare_servers(表示闲着的worker太多了)则会杀掉一些worker,避免占用过多资源,master通过这4个值来控制worker数

3.ondemand: 这种方式一般很少用,在启动时不分配worker进程,等到有请求了后再通知master进程fork worker进程,总的worker数不超过pm.max_children,处理完成后worker进程不会立即退出,当空闲时间超过pm.process_idle_timeout后再退出

PHP-FPM事件管理器

1.sp[1]管道可读事件:这个事件是master用于处理信号的

2.fpm_pctl_perform_idle_server_maintenance_heartbeat():这是进程管理实现的主要事件,master启动了一个定时器,每隔1s触发一次,主要用于dynamic、ondemand模式下的worker管理,master会定时检查各worker pool的worker进程数,通过此定时器实现worker数量的控制

3.fpm_pctl_heartbeat():这个事件是用于限制worker处理单个请求最大耗时的,php-fpm.conf中有一个request_terminate_timeout的配置项,如果worker处理一个请求的总时长超过了这个值那么master将会向此worker进程发送kill -TERM信号杀掉worker进程,此配置单位为秒,默认值为0表示关闭此机制

4.fpm_pctl_on_socket_accept():ondemand模式下master监听的新请求到达的事件,因为ondemand模式下fpm启动时是不会预创建worker的,有请求时才会生成子进程,所以请求到达时需要通知master进程

PHP 相关文章推荐
PHP 面向对象详解
Sep 13 PHP
浅析PHP页面局部刷新功能的实现小结
Jun 21 PHP
PHP多例模式介绍
Jun 24 PHP
Windows下的PHP 5.3.x安装 Zend Guard Loader教程
Sep 06 PHP
php文档工具PHP Documentor安装与使用方法
Jan 25 PHP
如何批量清理系统临时文件(语言:C#、 C/C++、 php 、python 、java )
Feb 01 PHP
laravel学习教程之存取器
Jul 30 PHP
php微信公众平台交互与接口详解
Nov 28 PHP
Discuz论坛密码与密保加密规则
Dec 19 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
Feb 17 PHP
PHP实现的折半查找算法示例
Dec 19 PHP
PHP实时统计中文字数和区别
Feb 28 PHP
Codeigniter里的无刷新上传的实现代码
Apr 14 #PHP
PHP7中I/O模型内核剖析详解
Apr 14 #PHP
浅析PHP7的多进程及实例源码
Apr 14 #PHP
什么是PHP7中的孤儿进程与僵尸进程
Apr 14 #PHP
php intval函数用法总结
Apr 14 #PHP
PHP中上传文件打印错误错误类型分析
Apr 14 #PHP
PHP扩展Swoole实现实时异步任务队列示例
Apr 13 #PHP
You might like
社区(php&&mysql)六
2006/10/09 PHP
PHP中Date获取时间不正确怎么办
2008/06/05 PHP
用php的ob_start来生成静态页面的方法分析
2011/03/09 PHP
php实现12306火车票余票查询和价格查询(12306火车票查询)
2014/01/14 PHP
php实现插入数组但不影响原有顺序的方法
2015/03/27 PHP
php实现简单的MVC框架实例
2015/09/23 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
JS 中document.URL 和 windows.location.href 的区别
2009/11/11 Javascript
jquery入门必备的基本认识及实例(整理)
2013/06/24 Javascript
js完美的div拖拽实例代码
2014/01/22 Javascript
JavaScript字符串对象toUpperCase方法入门实例(用于把字母转换为大写)
2014/10/17 Javascript
js实现进度条的方法
2015/02/13 Javascript
JS网页在线获取鼠标坐标值的方法
2015/02/28 Javascript
js验证框架实现代码分享
2016/05/18 Javascript
Javascript中作用域的详细介绍
2016/10/06 Javascript
Bootstrap CSS组件之导航条(navbar)
2016/12/17 Javascript
JS中IP地址与整数相互转换的实现代码
2017/04/10 Javascript
vue.js动态数据绑定学习笔记
2017/05/19 Javascript
轻松理解vue的双向数据绑定问题
2017/10/30 Javascript
如何给element添加一个抽屉组件的方法步骤
2019/07/14 Javascript
layui自己添加图片按钮并点击跳转页面的例子
2019/09/14 Javascript
[47:04]EG vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python爬虫实战之12306抢票开源
2019/01/24 Python
pyqt5 tablewidget 利用线程动态刷新数据的方法
2019/06/17 Python
Python3 io文本及原始流I/O工具用法详解
2020/03/23 Python
Python3标准库之threading进程中管理并发操作方法
2020/03/30 Python
tensorflow2.0的函数签名与图结构(推荐)
2020/04/28 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
2020/09/28 Python
css3实现画半圆弧线的示例代码
2017/11/06 HTML / CSS
英国最大的LED专业零售商:Led Hut
2018/03/16 全球购物
Skyscanner澳大利亚:全球领先的旅游搜索网站
2018/03/24 全球购物
2015年财务部年度工作总结
2015/05/19 职场文书
建国70周年的心得体会(2篇)
2019/09/20 职场文书
Mysql分库分表之后主键处理的几种方法
2022/02/15 MySQL
python文件与路径操作神器 pathlib
2022/04/01 Python
高通2023 年将发布高性能PC处理器
2022/04/29 数码科技