一直以来都对PHP执行的流程有点迷糊,这次花点时间整理下:
PHP是单进程执行的,处理并发主要是依赖服务器或者PHP-FPM的多进程以及它们进程的复用。
CGI
Common Gateway Interface,公共网关接口,是Web服务器运行时外部程序的规范,按CGI编写的程序可以扩展服务器的功能。简单的说就是Web服务器和一个扩展的外部程序之前的协议。
- 把
HTTP请求Requst的Header头设置成进程的环境变量 - 把
HTTP请求的Body正文设置成进程的标准输入 - 进程的标准输出设置为
HTTP响应Response
通过CGI接口,Web服务器就能够将获取的客户端数据转交给服务器端的CGI程序去处理(PHP对应的CGI程序是php-cgi.exe)。
流程:用户请求动态脚本,Web服务器Fork创建一个新进程去启用CGI程序,由CGI程序处理动态脚本,处理完成后进程随之关闭。
PHP-CGI:php语言对CGI接口规范的实现是php-cgi.exe,也是php的解释器
FastCGI
和CGI一样,是CGI的改进版本,Web服务器与处理程序之间通信的一种协议,FastCGI是常驻内存的CGI服务。
CGI针对每个HTTP请求都会fork一个新进程来进行处理(解析配置文件、初始化执行环境、处理请求),然后把这个进程处理完的结果通过Web服务器转发给用户,完成后fork的新进程也随之退出,如果下次用户再请求动态资源,那么Web服务器又再次fork一个新进程,如此周而复始循环往复。
而 FastCGI 则会先 fork 一个 master 进程,解析配置文件,初始化执行环境,然后再 fork 多个 worker 进程(与 Nginx 有点像),当 HTTP 请求过来时,master进程将其会传递给一个worker进程,然后立即可以接受下一个请求,这样就避免了重复的初始化操作,效率自然也就提高了。而且当 worker 进程不够用时,master 进程还可以根据配置预先启动几个 worker 进程等着;当空闲 worker 进程太多时,也会关掉一些,这样不仅提高了性能,还节约了系统资源。
PHP-FPM
FastCGI Process Manager,是PHP对FastCGI的一种具体实现,是fast-cgi进程管理工具,常驻内存,PHP-FPM负责Fork多个进程,每个进程都运行着PHP解释器 包含master进程和worker进程两种。
master进程只有一个,负责监听端口,接收来自Web Server的请求worker进程有多个(可以配置),每个进程内部都嵌入了一个PHP解释器,是PHP代码真正执行的地方