0

假设当前负载较小,prefork 模式下的 apache 维持的最小空闲进程数的处理能力完全能满足请求量,也就是说这些进程在没有达到 MaxRequestsPerChild 时不会被回收销毁。那么这些常住内存的 php_mod 进程是否等同于 php-fpm 里的常住内存的 fast-cgi 进程呢?他们持有资源是否相同?

我自己理解的 php 的 fast-cgi 进程创建时载入 php解释器,php.ini 和 各项依赖 创建好 php的执行环境并持有,处理请求时只需重复的载入需要处理的 php 脚本即可。

那 apache 的 php_mod 都载入了什么?是同 php 的 fast-cgi 所持有的相同,还是说只是个引导模块,请求到达时才会去载入 php解释器,php.ini 和 各项依赖,即使 apache 没有回收此进程,它在处理完请求后也会释放所持有的 php 的所有资源,下个请求到来时重新载入 php解释器,php ini 和 各项依赖,只不过 apache 节省了创建进程的开支,和 php 相关的东西都会被一次次的重新载入?

说了这么多,其实就一句话:php_mod 进程有没有预加载并持有 php执行的环境,请求到达时只需要载入相应的 php 脚本即可,还是说 php_mod 进程每次都要重复的初始化 php 的执行环境?

2个回答

0

已采纳

我自问自答好了。

最近一段时间查阅了 php 内部执行流程的相关资料,可以明确的理解此问题了。

php 的 sapi 有 cgi/cli/mod_php/fast-cgi/isapi
一个 php 进行将会粗略的经历以下 4 步:

1、minit 模块初始化:启动 php 进程(解释器,zend 引擎),读取 php.ini,加载并初始化相关扩展和模块,redis.so 等
2、rinit 请求初始化:处理请求信息,比如: GET index.php HTTP1.1/ php cli_index.php。处理好请求信息后便会载入相应的业务源码,并准备开始执行
=====================================执行业务=============================================
3、rshutdown 关闭请求:返回处理状态和相关结果数据给请服务器,服务器返回给客户端,清理内存,释放资源
4、mshutdown 关闭模块:关闭相关扩展和模块,关闭 php 进程(解释器,zend 引擎)

可以看出对于 php 服务来说,只有 2 和 3 两步会因为请求的不同而做一些不同的处理,1 和 4 则是相同的,直到你下一次修改配置。

但需要理解的是:

cgi/cli 是以 1,2,3,4 的步骤去执行,每次执行都会进行这四部。

mod_php/fast-cig/ispai 则是在启动进程时执行 1,然后等待请求。请求到达时执行 2 和 3 ,但并不会继续执行 4 ,除非进程被回收。这也是为什么 mod_php/fast-cgi 模式效率要高于 cgi 模式,1 / 4 两步本身就是可重复利用的。

mod_php 并不是败给了 php-fpm,而是败给了 nginx + php-fpm。单纯的比较一个 mod_php 进程的执行效率可能并不比 php-fpm 的 fast-cgi 进程慢,甚至速度还要快一些,所以 apache 是因为自己的 IO 模型而失势在响应速度阶段,处理速度并不比 php-fpm 慢,但面向请求来讲处理时间 = 响应时间 + 处理 + 响应结束 整个过程,所以 apache 还是慢了下来。但 apache 的 进程模型 和 IO 模型导致了它没办法灵活快速的响应突发的高并发和高并发所带来的巨大流量,而这却是 nginx 的特性。

所以在 mod_php 或 fast-cgi 启动时,php 引擎也同时完成了相关初始化工作,读取配置并载入相关扩展和模块。然后等待请求,请求到来时进行请求初始化,分析请求,载入我们的脚本,处理数据,返回数据,清理本次请求的数据和资源,但并不会关闭 php 引擎,会继续回到等待请求的哪一步。

0

http://fastjoomlahost.com/mod...

我觉得这篇文章可以参考下,mod_php的作用是可以把php嵌入到apache,这样apache能直接运行php程序,不需要单独开一个php进程,理论上会比php-fpm资源占用更小。

撰写答案