Skip to the content.

FPM

概述

FPM(FastCGI Process Manager)是 PHP FastCGI 运行模式的一个进程管理器.

FastCGI 是 Web 服务器和处理程序之间的一种通信协议, 是与 Http 类似的一种应用层通信协议.

PHP 只是一个脚本解析器, 没有自带的 http 网络库.

web 服务器处理 http 请求, 将解析结果通过 FastCGI 协议转发给处理程序,处理程序处理完后将结果返回给 web 服务器,web 服务器再返回给用户.

fpm 的实现: 创建一个 master 进程,在 master 进程中创建并监听 socket,然后 fork 出多个子进程,这些子进程各自 accept 请求,子进程启动后将阻塞在 accept 上,有请求大道后开始读取请求数据,读取完成后开始处理然后返回,在这个期间是不会接收其它请求的

fpm 的子进程同时只能响应一个请求

nginx 事件驱动有很大区别,nginx 的子进程通过epoll管理套接字,一个请求数据还未发送完毕则会处理下一个请求, 即单进程处理多个请求, 非阻塞的模型, 只处理活跃的套接字

fpm 的 master 通过共享内存获取 worker 进程的信息(worker 当前状态,已处理请求),master 进程杀掉 worker 时通过发送信号的方式通知

fpm 可以同时监听多个端口,每个端口对应一个 worker pool, 每个 pool 下对应多个 worker 进程

worker pool 通过fpm_worker_pool_s结构表示

FPM 初始化

  1. sapi_startup(&cgi_sapi_module) // 注册 SAPI:将全局变量 sapi_module 设置为 cgi_sapi_module
  2. cgi_sapi_module.startup() // 执行 php_module_startup()
  3. fpm_init() // 初始化
  1. fpm_run() // 启动 worker 进程

请求处理

fpm_run执行后将 fork 出 worker 进程,worker 进程返回main()中继续向下执行,后面的流程就是 worker 进程不断 accept 请求,然后执行 PHP 脚本并返回.

master 进程将永远阻塞在fpm_event_loop(), worker 将继续后面的处理

  1. 等待请求: worker 进程阻塞在 fcgi_accept_request()等待请求;
  2. 解析请求: fastcgi 请求大道后被 worker 接收,然后开始接收并解析请求数据,直到 request 数据完全到达;
  3. 请求初始化: 执行 php_request_startup(),此阶段会调用每个扩展的: PHP_RINIT_FUNCTION();
  4. 编译,执行: 由 php_execute_script()完成 PHP 脚本的编译,执行;
  5. 关闭请求: 请求完成后执行 php_request_shutdown(), 此阶段会调用每个扩展的: PHP_RSHUTDOWN_FUNCTION(), 然后进入步骤 1 继续等待下一个请求;

worker 进程一次请求的处理被划分为 5 阶段:

worker 的处理阶段会更新到fpm_scoreboard_proc_s->request_stage, master 进程通过这个判断 worker 是否空闲的

进程管理

master 是如何管理 worker 进程的

master 进程管理中主要用到的几个事件

sp[1]管道可读事件

这个事件是 master 用于处理信号的

fpm_pctl_perform_idle_server_maintenance_heartbeat()

进程管理实现的主要事件, master 启动了一个定时器,每隔 1s 触发一次,主要用于 dynamic,ondemand 模式下的 worker 管理

fpm_pctl_heartbeat()

这个事件是用于限制 worker 处理单个请求最大耗时的,超过request_terminate_timeout配置项后,master 将会向此进程发送kill -TERM信号杀掉 worker 进程, 默认是关闭的. fpm slow log 也在这里完成