php-fpm原理

5 篇文章 0 订阅

php-fpm的运行原理

master进程工作流程: cgi初始化->php环境初始化->php-fpm初始化->php-fpm运行
  1. cgi初始化阶段:分别调用fcgi_init()和 sapi_startup()函数,注册进程信号以及初始化sapi_globals全局变量。

  2. php环境初始化阶段:由cgi_sapi_module.startup 触发。实际调用php_cgi_startup函数,而php_cgi_startup内部又调用
    php_module_startup执行。

    php_module_startup主要功能:

    • 加载和解析php配置;
    • 加载php模块并记入函数符号表(function_table);
    • 加载zend扩展 ;
    • 设置禁用函数和类库配置;
    • 注册回收内存方法;
  3. php-fpm初始化阶段:执行fpm_init()函数。负责解析php-fpm.conf文件配置,获取进程相关参数(允许进程打开的最大文件数等),初始化进程池及事件模型等操作。

  4. php-fpm运行阶段:执行fpm_run() 函数,运行后主进程发生阻塞。该阶段分为两部分:fork子进程 和 循环事件。fork子进程部分交由fpm_children_create_initial函数处理( 注:ondemand模式在fpm_pctl_on_socket_accept函数创建)。循环事件部分通过fpm_event_loop函数处理,其内部是一个死循环,负责事件的收集工作。

worker进程工作流程: 接收客户端请求->处理请求->请求结束
  1. 接收客户端请求:执行fcgi_accept_request函数,其内部通过调用accept 函数获取客户端请求。
//请求锁
FCGI_LOCK(req->listen_socket);
req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len);
//释放锁
FCGI_UNLOCK(req->listen_socket);12345

从上面的代码,可以注意到accept之前有一个请求锁的操作,这么设计是为了避免请求出现“惊群”的现象。当然,这是一个可选的选项,可以取消该功能。

  1. 处理请求阶段:首先,分别调用fpm_request_info、php_request_startup获取请求内容及注册全局变量
    然后根据请求信息调用php_fopen_primary_script访问脚本文件;最后交给php_execute_script执行。php_execute_script内部调用zend_execute_scripts方法将脚本交给zend引擎处理。
  2. 请求结束阶段:执行php_request_shutdown函数。此时 回调register_shutdown_function注册的函数及__destruct()方法,发送响应内容、释放内存等操作

php-fpm / cgi 和 fast-cgi

php-fpm 它是一个实现了fast-cgi 协议的程序,用来管理fast-cgi 起的进程,即能够调度php-cgi进程的程序。

php-fpm采用master/worker架构设计, master进程负责CGI、PHP公共环境的初始化及事件监听操作。worker进程负责请求的处理功能。在worker进程处理请求时,无需再次初始化PHP运行环境,这也是php-fpm性能优异的原因之一。

  1. php-fpm启动的时候,当请求过来时, cgi 每次连接都会fork 一个cgi进程来进行处理请求,当高并发时,不可用。
  2. fast-cgi 是在 cgi 的基础上改进的,php-fpm启动会先fork一个master,解析配置文件,初始化执行环境,然后再fork多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是fast-cgi 的对进程的管理。

总结:就是cgi 每次都会执行解析配置文件,初始化环境,所以处理每个请求会比较长,而fastcgi 不用,fastcgi 会先启动一个master 进程,完成一系列的初始化操作,然后启动多个worker , worker处理请求。

php-fpm / master进程 和 work进程的关系

php-fpm中master主进程是不负责分发请求的,只负责监控管理worker进程,负责监听请求的是worker进程。

  1. 当kill掉worker进程后,会重启一个新的worker进程。因此客户端请求肯定会得到响应处理。master进程负责监听子进程的状态,子进程挂掉之后,会发信号给master进程,然后master进程重新启一个新的worker进程。
  2. 当kill掉master进程后,子进程并不会死掉,程序正常运行。

最后来一张图说明一下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝颜~岁月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值