php-fpm 是一种 master(主)/worker(子)多进程架构,与 nginx 设计风格有点类似。master 进程主要负责 CGI 及 PHP 环境初始化、事件监听、子进程状态等等, worker 进程负责处理 php 请求。
master 只是负责管理工作,并不是很多人认为的把客户端发来的请求分给 worker 进程处理,而是由 worker 进程负责客户端的请求监听和处理, master 只负责管理 worker,如重启,重新加载配置文件,并不会派发请求。
一旦 kill 掉 worker 进程后,会重启一个新的 worker 进程。因此客户端请求肯定会得到响应处理。这进一步验证了的上面的结论,master 进程负责监听子进程的状态,子进程挂掉之后,会发信号给 master 进程,然后 master 进程重新启一个新的 worker 进程。
worker 是同步阻塞, 必须等这次处理完,才会处理其它请求, 并发性能不行.
nginx 与 php-fpm 的结合,完整的流程是这样的。
www.example.com
|
|
Nginx
|
|
路由到 www.example.com/index.php
|
|
加载 nginx 的 fast-cgi 模块
|
|
fast-cgi 监听 127.0.0.1:9000 地址
|
|
www.example.com/index.php 请求到达 127.0.0.1:9000
|
|
php-fpm 监听 127.0.0.1:9000
|
|
php-fpm 接收到请求,启用 worker 进程处理请求
|
|
php-fpm 处理完请求,返回给 nginx
|
|
nginx 将结果通过 http 返回给浏览器
1. 传统 php-fpm 工作模式的问题
1、Fastcgi 进程管理器,实现 fastcgi 协议
2、同步阻塞 IO 进程模型
3、请求结束后释放所有资源和内存
4、并发受限于进程数
5、PHP 框架初始化占用大量的计算资源
2. php-fpm 工作模式的问题
1、nginx 基于 epoll 事件模型,一个 worker 同时可处理多个请求
2、fpm-worker 在同一时刻可处理一个请求
3、master 进程只负责处理 worker 进程的监控、日志等
4、用户端请求由 elb 解析,再经过 nginx 解析
5、fpm-worker 每次处理请求前需要重新初始化 mvc 框架,然后再释放资源
6、高并发请求时,fpm-worker 不够用,nginx 直接响应 502
7、fpm-worker 进程间切换消耗大(如某线上业务在 4 核 8G 内存服务器实质可利用 16 个进程)