资讯专栏INFORMATION COLUMN

深入了解SAPI

CoderBear / 3325人阅读

摘要:将环境变量和标准输入发送到子进程子进程完成处理后将标准输出和错误信息从同一连接返回。当子进程关闭连接时,请求便告知处理完成。定义一个子进程最多处理的请求数,达到这个值,进程自动退出。

一、SAPI比较 1. SAPI

服务器应用程序编程接口,就是服务器与编程语言之间交互的接口。比如Linux命令行执行一段PHP代码,其实是Linux shell通过PHP SAPI传入一组参数,zend引擎执行后返回给shell。在PHP生命周期的各个阶段,一些与服务相关的操作都是通过SAPI接口实现。

php_sapi_name()可以查看当前SAPI接口的类型。  
如 cli(php -r "echo php_sapi_name();")、fpm-fcgi等
2. PHP运行和加载的4个阶段

①Minit 模块初始化阶段,可以初始化php扩展、类库的内部变量、注册常量,定义模块使用的类等。

②Rinit 请求初始化阶段,在模块初始化并激活后,会创建PHP运行环境,初始化本次请求所需的环境变量,比如 $_SERVER,$_SESSION

③Rshutdown 请求关闭阶段,执行最后的清理工作,释放所有处理本次请求的资源(申请的变量)。请求完成可能是执行到脚本完成,也可能是调用die()或exit()函数完成

④Mshutdown 模块回收阶段,用于关闭自己的内核子系统,释放没存。

3. SAPI 5种运行模式

①单进程模式(CLI,CGI),每次执行PHP脚本,都会执行第二部分讲的四个INT和Shutdown事件。当用户请求数量非常多时,会大量挤占系统的资源如内存,CPU时间等,造成系统开销很大

②多进程模式(Apache下的prefork MPM模式),会fork很多子进程,每个子进程拥有自己独立的进程地址空间,在一个子进程中,PHP的生命周期是调用MINT启动后,执行多次请求(RINT/RSHUTDOWN),在Apache关闭或进程结束后,才会调用MSHUTDOWN进行回收阶段。
多进程模型中,每个子进程都是独立运行,没有代码和数据共享,因此一个子进程终止退出和重新生成,不会影响其他子进程的稳定。

③多线程模式(Apache2的Worker MPM),在一个进程下创建多个线程,在同一个进程地址空间执行

④fastCGI模式,nginx+php-fpm就是这个模式,fast-cgi是CGI的升级版本,FastCGI可以看成是一个常驻型的CGI,它可以一直执行着,运行后可以fork多个进程,不用花费时间动态Fork子进程。也不需要每次请求都调用MINT/MSHUTDOWN。
⑤内嵌模式,允许在C/C++语言中调用PHP提供的函数,运行模式和CGI一样,执行4个阶段

二、php-fpm运行原理

CGI:是个协议,服务器发起请求,传给PHP解析器,传递哪些数据,以什么格式,由CGI决定

fastcgi:是个协议,提高CGI性能的,不用每次都去初始化,进程不够用,会预先启动几个进程,进程空闲太多了也会停掉一些,fastCGI对进程的管理,提高性能,节约了资源

php-fpm:实现fastCGI协议的程序,被PHP官方收了,也提供了进程管理功能,进程包含 master 进程和 worker 进程两种进程。 master 进程只有一个,负责监听端口分发请求,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。

php-cgi:cgi解释器进程

FastCGI的工作原理:

Web Server启动时载入FastCGI进程管理器

FastCGI进程管理器自身初始化,启动多个CGI解释器(可见多个php-cgi)并等待来自Web Server的连接

当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web Server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi

FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告知处理完成。FastCGI子进程接着等待并处理来自FastCGI继承管理器的下一个连接

使用FastCGI,系统开销小。另外,对于数据库和Memcache的持续连接可以工作。

数据库短连接connect:请求关闭阶段,释放请求所用的资源,数据库连接句柄也会被释放 

数据库长连接pconnect:请求关闭后,PHP会收留此次连接,即使主动关闭也不会关闭而是收留,下次有打开相同连接的请求时,PHP直接把收留的句柄拿出来,省去建立连接的过程。

php-fpm实现长连接也需要配合数据库一些配置,一个进程收留一个连接,数据库连接的数量就是子进程数量,所以数据库允许连接数就要大于子进程数。

三、php-fpm进程管理的三种模式

php-fpm支持三种运行模式,分别为static、ondemand、dynamic,默认为dynamic 。

static : 静态模式,启动时分配固定的worker进程。只需要考虑max_children的数量,数量取决于cpu的个数和应用的响应时间。

ondemand: 按需分配,启动时不分配任何进程,当收到用户请求时才启动进程。 master进程检查work进程的数量是否受限,是否有空闲的work进程,没有就新建work进程。在大流量的系统上master进程会变得繁忙,占用系统cpu资源,不适合大流量环境的部署。

dynamic: 动态模式,启动时分配固定的进程。伴随着请求数增加,在设定的浮动范围调整worker进程。

 pm = dynamic  //动态进程管理,对于专用服务器,可以设置为static,静态一次性启动最大子进程数,不会变化。
 
 pm.max_children = 50 //最大子进程数,ps aux可以查看
 
 pm.start_servers = 20 //启动服务时会启动的进程数
 
 pm.min_spare_servers = 5 //保证空闲子进程数的最小值,如果空闲进程小于这个值,php-fpm服务会创建新的子进程。
 
 pm.max_spare_servers = 35 //保证空闲子进程数的最大值,如果空闲进程高于这个值,就进行清理。
 
 pm.max_requests = 500  //定义一个子进程最多处理的请求数,达到这个值,进程自动退出。目的是为了控制内存溢出,使内存在一个可控范围内。但是如果设置的很小,有可能多个进程同时达到这个值,同时重启,就会导致PHP停止响应直到重启完毕。设置为0表示一直接受请求。
 
四、php-fpm慢日志

如果一个php网站可以访问,就是访问速度变慢了,可以通过php-fpm的慢执行日志,清晰的了解到php的脚本哪里执行时间长,它可以定位到具体的代码行

 vim /usr/local/php/etc/php-fpm.d/www.conf
 request_slowlog_timeout = 1 //超时时间
 slowlog = /usr/local/php/var/log/www-slow.log
 重启php-fpm /etc/init.d/php-fpm reload

我在php文件中加了一行sleep(3);,运行之后返回结果

参考文献

1、https://www.jianshu.com/p/c9a... php-fpm进程管理的三种模式
2、https://www.jb51.net/article/... SAPI的5种运行模式
3、http://blog.51cto.com/1260661... php-fpm慢日志
4、https://www.cnblogs.com/wpjam... php-fpm与mysql长连接

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30052.html

相关文章

  • PHP回顾之执行流程及相关概念

    摘要:通过,脚本层无需过多考虑执行的具体环境,而本身则可以让针对自己的特点给出特有实现。模式下,也只执行一次。这几个概念的关系如下网关协议,与语言无关,所以与关系也不大。总结本文简要回顾了程序的架构和执行流程,并对几个容易混淆概念做了介绍。 转载请注明文章出处:https://tlanyan.me/php-review... PHP回顾系列目录 PHP基础 web请求 cookie we...

    jsdt 评论0 收藏0
  • PHP的生命周期

    摘要:的启动和终止请求之前的开始阶段模块初始化阶段。的生命周期单进程生命周期多进程生命周期多线程的生命周期是一种比较特殊的,容许你在语言中调用提供的函数。不太了解,明天看一下综述理一下的生命周期,以及整个执行过程。 PHP的架构图 showImg(https://segmentfault.com/img/remote/1460000013321599?w=514&h=525); SAPI S...

    sf190404 评论0 收藏0
  • 【PHP7源码分析】PHP中$_POST揭秘

    摘要:和进程的启动过程类似,启动过程有种进程角色启动进程进程和进程。直到请求到来,将连接赋值给对象的字段。注当进程执行完后会再次调用函数,准备监听新的请求。当读取到的时,会调用函数对进行解析,将中的以及存储到结构体中。 运营研发团队 季伟滨 一、前言 前几天的工作中,需要通过curl做一次接口测试。让我意外的是,通过$_POST竟然无法获取到Content-Type是application...

    sf190404 评论0 收藏0
  • PHP源码研究

    摘要:最近闲来无事,所以对这门语言进行更深一层的了解,对源码进行一番研究,是如何执行我们写的脚本的。引擎是语言实现的最为重要的部分,是最基础最核心的部分,它的源码在目录下,代码从编译到执行都是由完成的,后面章节绝大部分的源码分析都是针对的。 最近闲来无事,所以对PHP这门语言进行更深一层的了解,对源码进行一番研究,是如何执行我们写的PHP脚本的。 1.1.3 PHP的相关组成 1.1.3.1...

    Developer 评论0 收藏0
  • SAPI 基于Spring极度简单的Restful API工具

    摘要:是一个及其精简的输出工具,诞生的背景是基于目前微服务开发接口,很多中小型项目开发人员在对接口测试时不仅需要使用等进行业务接口测试,还需要对进行自测。目前只需要开发人员引入后再启动类加入一行文件即可。中的路径不要忽略。 SAPI是一个及其精简的Restful API输出工具,诞生的背景是基于目前微服务开发接口,很多中小型项目开发人员在对接口测试时不仅需要使用JUnit等进行业务接口测试,...

    Keven 评论0 收藏0

发表评论

0条评论

CoderBear

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<