PHP运行原理

256 阅读6分钟

PHP的四层体系

  1. Zend引擎,将源文件转换成机器语言(字解码OpCode),然后在虚拟机(zend VM)上运行,实现基本的数据结构,内存分配,提供api方法供外部调用,所有外围的功能都是围绕zend实现的。
  2. Extensions:通过组件的形式提供各种基础服务,如各种内置函数(array函数),标准考库等
  3. sapi: 全称 server application programming interface 服务端应用编程接口,sapi通过一系列钩子函数,使php可以和外界数据交互。sapi实现了与上层应用隔离,解耦的效果。
  4. 上层应用:就是我们编写的程序,通过实现sapi的方式得到各种应用,如web应用,cli等

SAPI server application programming interface

www.cnblogs.com/walblog/art… www.laruence.com/2008/08/12/… blog.csdn.net/raoxiaoya/a…

全称服务端应用编程接口,是php和上层应用的交互的桥梁,包含cgi,fast-cgi,ISAPI,APACHE2HANDLER等

主要分为: cli 和cgi两类

为什么PHP要使用fastcgi呢,还搞出这么多运行模式? 为了配合apache服务器,实现了 apache2handler。 为了配合nginx服务器,实现了 fastcgi。 之前还有基于IIS的协议实现。

cgi 协议

通用网关接口 Common gateway interface

php-cgi程序是实现这个协议的程序。

webserver和PHP交互的一种方式,遇到连接请求时,会先创建和激活一个cgi进程,然后处理请求,然后结束这个cgi进程,这就是fork-and-execute模式。

有多少请求就会有多少cgi进程被fork,kill,进程反复加载是cgi模式性能低下的主要原因。

fast-cgi 协议

fast-cgi只是一种协议,cgi的升级版本,是一个常驻型cgi, 不用每次fork cgi进程。fast-cgi每次处理完请求后,不会kill掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。这样每次就不用重新fork一个进程了,大大提高了效率。

PHP-fpm (linux)

fast-cgi process manager PHP-fpm是实现并管理fast-cgi的进程管理器,提供进程管理功能。实现看fastcgi协议(初期是依赖于php.cgi程序的,后面继承了)

phpfpm 可以平滑启动加载配置 , php-cgi无法平滑启动

PHP-fpm启动时:会创建进程,包含一个 master 进程和多个 worker 进程两种进程。

master进程: 负责监听端口,解析配置文件,初始化环境。接受webserver的请求传递给worker

worker进程:每个进程内部都嵌入PHP解析器(php-cgi),负责处理PHP程序

502 master进程没有找到可用的worker进程 504:worker处理超时

运行模式:

  1. web server 启动时载入php-fpm (IIS的ISAP ,apache的fast-cgi模块,nginx的php-fpm等)
  2. php-fpm自身初始化,加载配置等,启动多个cgi进程(php-cgi)等待webserver的连接。
  3. 有请求时,php-fpm选择一个cgi进程执行,web server将cgi环境变量和标准输入发送给php-cgi子进程
  4. php-cgi子进程处理完后,将标准输出信息从同一连接返回给web server,关闭并等待下个连接。

nginx配置 fastcgi_pass 127.0.0.1:9000; #nginx fastcgi进程监听的IP地址和端口

nginx-phpfpm运行过程

zhuanlan.zhihu.com/p/112720502

  1. 启动fpm,支持2种通讯模式:TCP socket和Unix socket
  2. 启动nginx ,载入ngx_http_fastcgi_module 模块,初始化fastcgi执行环境,实现fastcgi协议请求代理
  3. Nginx 接收请求,并基于location配置,选择一个合适handler(负载均衡)
  4. Nginx 把请求翻译成fastcgi请求(标准输入)发给fpm
  5. master 分配任务给worker,PHP-FPM Worker 进程返回处理结果,并关闭连接,等待下一个请求
  6. PHP-FPM Master 进程通过Socket 返回处理结果,Nginx Handler顺序相应

php-fpm三种运行模式

pm=static 静态模式: 固定数量子进程,不灵活,不推荐

pm=dynamic 动态模式: 启动时创建最小进程数(pm.start_servers),并根据请求在最大进程数(pm.max_childrem)之间波动,闲置的子进程由另外2个配置控制,分别是pm.min_spare_servers和pm.max_spare_servers,多余闲置进程会被kill掉,还会剩下一些闲置进程被保留。例如忙碌是创建50个进程,然后kill掉20个多余闲置,不忙碌时可能还有30个闲置进程,比较消耗内存,需要重启fpm。

服务器响第一位,这种模式很灵活,也是默认选项,dynamic模式为了最大化的优化服务器响应,会造成更多内存使用

pm=ondemand 按需模式:启动时,创建最小进程(pm.start_servers),每个闲置进程在持续闲置了pm.process_idle_timeout秒后就会被杀掉

内存放到第一位,pm.process_idle_timeout设置太短的话,会造成重复创建子进程


配置文件位置:/usr/local/php/etc/php-fpm.cofg

pm = dynamic: 动态模式
pm.max_children:静态方式下开启的PHP-FPM进程数量
pm.start_servers:动态方式下的起始PHP-FPM进程数量
pm.min_spare_servers:动态方式下的最小PHP-FPM进程数量
pm.max_spare_servers:动态方式下的最大PHP-FPM进程数量
pm.process_idle_timeout : 进程闲置超时时间,超时被杀掉 单位为s

linux

  1. 命令行模式 PHP是解析器
  2. php-cgi 是实现了fastcgi协议的php解释器,一般监听9000端口,php-cgi不具备管理进程的能力,所以一个端口只有一个进程来服务。
  3. phg-fpm 进程管理器,最初php-fpm是需要调用php-cgi来解释php代码的,php-fpm只起到进程管理的作用,在php5.4的时候,php-fpm就支持解析php代码,不在依赖php-cgi了。

windows运行原理

blog.csdn.net/raoxiaoya/a… blog.csdn.net/littlezhuhu…

window没有php-fpm进程管理器, 主要是以以下3种形式运行的

  1. apache的php_module,将php集成到apache模块中,apache加载dll执行php,以同一个进程运行。
  2. cgi/fastcgi模式,需要启动一个独立的程序 php-cgi.exe ,nginx和apache只要配置好,就可以将php脚本交给php-cgi.exe执行,
  • nginx的fastcgi配置: nginx反向代理,将请求发送到在9000端口的php-cgi.exe程序

    1. 启动php-cgi
    D:/php7.2.4/php-cgi.exe -b 127.0.0.1:9000  #启动程序,在9000端口监听
    
    1. 配置启动nginx, 反向代理给9000端口,是谁执行nginx并不关心
    fastcgi_pass   127.0.0.1:9000; # 这句
    
  • apache的fastcgi配置: apache 主动找php解析 告诉apache用什么执行 配置文件中:加载了mod_fcgid.so 模块,还需要配置额外的参数

    LoadModule fcgid_module modules/mod_fcgid.so
    
  1. 命令行模式下: php.exe是php的解析器

phpstudy会自动启动配置apache/nginx, php-cgi.exe程序。

xxfpm

windows环境下,php-cgi.exe的运行非常不稳定,运行一段时间后就会崩 溃退出。在linux中有fpm管理,在windows环境下现在比较好用的FastCGI进程管理器是xxfpm.exe

让xxfpm.exe管理php-cgi.exe,同进打开几个php-cgi.exe进程,当某个php-cgi.exe进程退出时,开启新的php-cgi.exe进程补上,使得php-cgi.exe的进程数目始终维持稳定。