FPM看这一篇就够了

Fpm是PHP FastCGI运行模式的一个进程管理器。FastCGI是Web服务器(如Nginx,Apache)和处理程序(如PHP)之间的一种通信协议,它是一种应用层通信协议。PHP处理完请求后将解析的结果再通过FastCGI协议转发给Web服务器,Web服务器再返回给用户。

基本实现

Fpm是一种多进程模型的进程管理器,它由一个master进程和多个worker进程组成。master进程启动时会创建一个socket,但是不会接收处理请求,而是由fork出的worker进程处理请求。master进程的作用就是负责fork或者杀掉worker进程。master在fork出worker进程后就会循环一个事件列表,然后由fork出的worker开始处理请求。worker—请求处理worker进程不断Accept请求,有请求到达后将读取并解析FastCGI协议的数据,解析完成后开始执行PHP脚本,执行完成后关闭请求。
各worker处理请求的步骤如下:
(1)等待请求:worker进程阻塞在fcgi_accept_request()中等待请求
(2)解析请求:fastcgi请求到达后被worker接收,然后开始接收并解析请求数据,直到request数据完全到达
(3)请求初始化:执行php_request_startup()
(4)执行PHP脚本
(5)关闭请求

表示worker进程的结构里有个参数用来记录worker当前所处的阶段fpm_scoreboard_proc_s->request_stage,一次请求过程中这个值将先后被设置为以下值
FPM_REQUEST_ACCEPTING:等待请求阶段
FPM_REQUEST_READING_HEADERS:读取fastcgi请求header阶段
FPM_REQUEST_INFO:获取请求信息阶段,此阶段是将请求的method,query string,request uri等信息保存到各worker进程的fpm_scoreboard_proc_s结构中,此操作需要加锁,因为master进程也会操作此结构FPM_REQUEST_EXECUTING:执行PHP脚本阶段
FPM_REQUEST_END:没有使用
FPM_REQUEST_FINISHED:请求处理完成

master–进程管理

master在调用完fpm_run()后不再返回,而是进入一个事件循环中,此后master将始终围绕着几个事件进行处理,在具体分析这几个事件之前,首先介绍Fpm三种不同的进程管理方式,具体要使用哪种模式可以在conf配置中通过pm指定,例如

pm=dynamic静态模式(static):这种方式比较简单,在启动时master根据pm.max_children配置fork出相应数量的worker进程,也就是worker进程数是固定不变的。

**动态模式(dynamic)?*这种模式比较常用,在Fpm启动时会根据pm.start_servers配置初始化一定数量的worker。运行期间如果master发现空闲worker数低于pm.min_spare_servers配置数(表示请求比较多,worker处理不过来了)则会fork worker进程,但总的worker数不能超过pm.max_children如果master发现空闲worker数超过了pm.max_spare_servers(表示闲着的worker太多了)则会杀掉一些worker,避免占用过多资源,master通过这四个值来动态控制worker的数量。

**按需模式(ondemand)?*这种模式很像传统的cgi,在启动时不分配worker进程,等到有请求了后在通知master进程fork worker进程,也就是来了请求后再fork子进程进行处理。总的worker数不超过pm.max_children,处理完成后worker进程不会立即退出,当空闲时间超过pm.process_idle_timeout后再退出。

master进程进入fpm_event_loop()事件循环,在这个方法中master将循环处理master注册的几个IO及定时器事件,当有事件触发时将回调具体的handler进行处理。
接下来具体看一下master注册的几个重要事件
**(1)**信号事件信号的处理函数是fpm_got_signal(),它会根据不同的信号进行相应的处理SIGINT/SIGTERM/SIGQUIT:退出Fpm,在master收到退出信号后将像所有的worker进程发送退出信号,通知worker退出,然后master退出。SIGUSR1:重新加载日志文件SIGUSR2:重启FpmSIGCHLD:这个信号是子进程退出时操作系统发送给父进程的,子进程退出时,操作系统将子进程设置为僵尸进程,它只保留最小的一些内核数据结构,以便父进程查询子进程的退出状态,只有当父进程调用wait()或者waitpid()函数查询子进程退出状态后子进程才终止,Fpm中当worker进程因为异常原因退出而非master主动杀掉时,master将收到此信号,这时父进程将调用waitpid()保证worker退出,然后检查是不是需要重新fork新的worker。

**(2)**进程检查定时器这个定时器就是用来定期检查worker进程数的,master通过这个定时器每隔一定时间检查worker的数量,根据不同策略(static/dynamic/ondemand)的配置决定是否需要fork或者kill进程

**(3)**执行超时检查定时器php-fpm.conf中有一个request_terminate_timeout的配置项,如果worker处理一个请求的总时长超过了这个值,那么master会向此worker进程发送kill -TERM信号杀掉worker进程,此配置单位为秒,默认值为0,表示关闭此机制。这个功能也是通过定时器实现的,master每隔一定时间检查所有处理中的worker,如果发现其处理时间达到阈值则杀掉这个worker。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值