基本原理:
浏览器访问网页的过程
请求静态页面
Browser(浏览器)
请求http://xxx.com/aa.html
-> Web Server(Nginx/Apache)分发 -> 找到aa.html
文件返回给Browser
。
请求动态脚本
Browser
请求http://xxx.com/bb.php
-> Web Server(Nginx/Apache)分发 -> PHP解析器
(PHP-CGI
程序)-> 返回处理结果给Web Server -> 返回数据给Browser。
原理:服务器根据配置文件
,知道这是一个PHP
脚本文件,需要去找PHP解析器
来处理。
PHP解析器
会解析php.ini
文件初始化执行环境,然后处理请求,再以标准的数据格式返回处理结果,最后退出进程。
CGI 程序到 FPM 进化史
CGI(Common Gateway Interface)
CGI
是服务器与后台语言交互的协议,有了这个协议,开发者可以使用任何语言处理服务器转发过来的请求,动态地生成内容,保证了传递过来的数据是标准格式
的(规定了以什么样的格式传哪些数据(URL、查询字符串、POST数据、HTTP header等等
)),方便了开发者。
PHP-CGI(PHP CGI)
PHP语言
对应与服务器交互的CGI程序
就是PHP-CGI
。
CGI程序
本身只能解析请求
、返回结果
,不会进程管理
,所以有一个致命的缺点,那就是每处理一个请求都需要fork
一个全新的进程,随着Web
的兴起,高并发越来越成为常态,这样低效的方式明显不能满足需求(每一次web请求
都会有启动和退出进程
,也就是最为人诟病的fork-and-execute
模式,这样一在大规模并发下,就死翘翘了)。
就这样,FastCGI
诞生了,CGI程序
很快就退出了历史的舞台。
FastCGI(Fast CGI)
FastCGI
,顾名思义就是更快的CGI程序
,用来提高CGI程序
性能,它允许在一个进程内处理多个请求
,而不是一个请求处理完毕就直接结束进程,性能上有了很大的提高。
- 提高性能?那么
CGI程序
的性能问题在哪呢?
PHP解析器
会解析php.ini
文件,初始化执行环境,就是这里了。
标准的CGI程序
对每个请求都会执行这些步骤(不闲累啊!启动进程很累的说!),所以处理每个请求的时间会比较长。这明显不合理嘛!
- 那么
FastCGI
是怎么做的呢?
首先,FastCGI
会先启一个master进程
,解析配置文件,初始化执行环境,然后再启动多个worker进程
。当请求过来时,master
会传递给一个worker
,然后立即可以接受下一个请求。
这样就避免了重复的劳动,效率自然是高。
而且当worker
不够用时,master
可以根据配置预先启动几个worker
等着。
当然空闲worker
太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是FastCGI
的对进程的管理。
ps:也有一些能够调度PHP-CGI进程
的程序,比如说由lighthttpd
分离出来的spawn-fcgi
。好了,PHP-FPM
也是这么个东东,在长时间的发展后,逐渐得到了大家的认可(要知道前几年大家可是抱怨PHP-FPM
稳定性太差的),也越来越流行。