FPM(FastCGI Process Manager)是PHP FastCGI运行模式的进程管理器,用于管理PHP进程池中的软件,并接收Web服务器的请求。
- FastCGI是Web服务器和处理程序之间的一种通信协议,与HTTP类似是一种应用层通信协议。
- PHP是一个脚本解析器,它输入的是PHP脚本,输出的是执行结果。
为什么会出现PHP-FPM呢?
FPM的出现是因为FastCGI的出现,为了更好的管理PHP-FastCGI而实现的一个程序。简单来说,FPM是FastCGI的一种实现。
什么是PHP-FastCGI呢?
PHP-FastCGI只是一个CGI程序,只会解析PHP请求并返回结果,由于不会管理,因此才出现了PHP-FPM。在PHP-FastCGI之前存在着PHP-CGI,只是PHP-CGI的运行效率底下,因此被PHP-FPM给替代了。
在网络应用场景中,PHP并没有像Golang实现了HTTP网络库,而是实现了FastCGI协议,然后与Web服务器配合实现了HTTP的处理。Web服务器用来处理HTTP请求,然后将解析结果通过FastCGI协议转发给处理程序,处理程序执行完毕后将结果返回给Web服务器,Web服务器在返回给终端用户。
PHP实现了FastCGI协议的解析,但并没有具体是实现网络处理,常见网络处理模型包括:多进程模型、多线程模型
- 多进程模型
主进程只负责管理子进程,基本的网络事件交由各个子进程处理,Nginx+FPM使用的是多进程模型。 - 多线程模型
多线程模型与多进程类似,区别在于它是线程粒度。多线程模式通常会由主线程监听并接收请求,然后交由子线程处理,主线程只负责管理子线程而不处理网络事件,各个子线程监听、接收并处理请求。Memcached使用UDP协议时采用的就是多线程模型。
FPM是如何进行工作的呢?
FPM启动后会创建一个Master主进程,在Master主进程中创建并监听Socket,然后Fork创建出多个CGI子进程,CGI子进程各自accept
接收请求并处理。简单来说,Master主进程负责管理CGI子进程并对外提供一个Socket套接字,当Web服务器要转发一个动态请求时,只需要按照FastCGI协议要求的格式将数据发往Socket套接字即可。CGI子进程会去争抢这个Socket连接,谁先抢到就先处理,处理完毕后将结果返回给Web服务器。
CGI子进程是如何处理请求的呢?
子进程在启动后阻塞在accept
上,当有请求到达时开始读取请求数据,读取完毕后开始处理最后再返回,在这个期间中子线程是不会接收其它请求的。也就是说,FPM的子进程同时只能响应一个请求,只有把这个请求处理完毕后才会accept
接收下一个请求,这一点与Nginx的事件驱动有很大的区别,在Nginx上子进程通过epoll
管理Socket套接字。如果一个请求数据还未发送完毕则会处理下一个请求,也就是一个进程会同时连接多个请求。因此,Nginx是非阻塞的模型,只处理活跃的Socket套接字。
FPM的Master主进程与Worker工作进程之间不会直接通信,Master通过共享内存获取Worker工作进程的信息,如Worker工作进程当前状态、已处理请求数据等。当Master主进程要杀死一个Worker工作进程时,则通过发送信号的方式通知Worker工作进程。
FPM可以同时监听多个端口,每个端口对应一个Work Pool工作线程池,每个工作线程池下对应多个Worker进程。类似于Nginx中Server服务器。
在php-fpm.conf
中通过pool name
声明一个Worker Pool工作进程池。
$ vim php-fpm.conf
启动FPM后查看进程
$ ps -aux|grep fpm
有疑问加站长微信联系(非本文作者)