SAPI php-fpm FastCGI原理介绍

淡淡de盐 · · 503 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

简介

SAPI (Server Application Programimg Interface,服务端应用编程接口) 是 PHP 框架的接口层,它是进入 PHP 内部的入口。其中包含了常见的 cli SAPI 和 fpm SAPI。

应用在终端上的 SAPI 就叫作 CLI SAPI,应用在 Web 服务器中的就叫作 CGI SAPI

php7源码架构

PHP 并没有像 Golang 那样实现 HTTP 网络库,而是实现 了 FastCGI协议。

PHP 定义好输入/输出规范,依据此规范与 PHP 交互的一方都可以称为 Server。这样做的好处便是 Server 方可以忽略 PHP 的内部实现,只要遵守定义好的 SAPI 协议,便可完成交互,极大丰富了 PHP 可以支持的 Server 类型。

Cli (Command Line Interface)

Cli 即命令行接口,用于在命令行下 执行 PHP 脚本,Cli 是单进程模式,处理完请求后就直接关闭了

生命周期

生命周期

Cli 过程比较简单,这里就不细说了。

Fpm (FastCGI Process Manager)

Fpm 是 PHP FastCGI 运行模式的一个进程管理器,Fpm 的核心功能是进程管理

生命周期

从 PHP 5.3.3 开始,PHP 集成了 PHP-FPM。PHP-FPM 提供了更好的 PHP 进程管理方式,可以有效控制内存和进程,支持平滑重启 PHP 及重载 PHP 配置。

Fpm 用来管理什么进程呢?

FastCGI 是 Web服务器(如Nginx、Apache)和处理程序之间的一种通信协议,它是与 HTTP 类似的一种应用层通信协议。注意:它只是一种协议!

以 Nginx 服务器为例,当有 http 协议请求发送到 Nginx 服务器,Nginx 按照 FastCGI 协议把请求交给 php-fpm 进程处理。

通信过程

FastCGI 协议与 Web 服务器配合实现了 HTTP 的处理,Web 服务器来处理 HTTP 请求,然后将解析的结果再通过 FastCGI 协议转发给处理程序,处理程序处理完成后将结果返回给 Web 服务器,Web 服务器再返回给用户

Client/Nginx/PHP-FPM通信示意图

Client 通过 HTTP 方式请求 Nginx,请求由 Nginx 的 worker 进行处理,转成对应的 FastCGI,请求 FPM, accept 由 FPM 的 worker 进程处理,执行完毕再返回给 Nginx, Nginx 再进一步返回给 Client。

PHP 实现了 FastCGI 协议的处理,但是并没有实现具体的网络处
理,比较常用的网络处理模型有以下两种。

  • 多进程模型: 由一个主进程和多个子进程组成,主进程负责管理子进程,基本的网络事件由各个子进程处理,Nginx采用的就是这种模型。
  • 多线程模型: 与多进程类似,只是它是线程粒度,这种模型通常会由主线程监听、接收请求,然后交由子线程处理,memcached 就是这种模式;有的也是采用多进程那种模式—主线程只负责管理子线程不处理网络事件,各个子线程监听、接收、处理请求,memcached 使用 UDP 协议时采用的是这种模式。

进程拥有独立的地址空间及资源,而线程则没有,线程之间共享进程的地址空间及资源,所以在资源管理上多进程模型比较简单,而多线程模型则需要考虑不同线程之间的资源冲突,也就是线程安全

多进程管理

Fpm 是一种多进程模型,它由一个 master 进程和多个 worker 进程组成。master 进程启动时会创建一个 socket,但是不会接收、处理请求,而是由 fork 出的 worker 子进程完成请求的接收及处理。

master 进程的主要工作是管理 worker 进程,负责 fork 或杀掉 worker 进程,请求多就 frok 新的 worker 进程,空间就杀掉部分子进程。

worker 进程的主要工作是处理请求,每个 worker 进程会竞争地 Accept 请求,接收成功后解析 FastCGI,然后执行相应的脚本,处理完成后关闭请求,继续等待新的连接

  • 为什么使用这种模式?
    从 worker 进程的生命周期可以看到,一个 worker 进程只能处理一个请求,只有将一个请求处理完成后才会处理下一个请求。这与Nginx的事件模型有很大的区别,Nginx 的子进程通过 epoll 管理套接字,如果一个请求数据还未发送完成则会处理下一个请求,即一个进程会同时连接多个请求,它是非阻塞的模型,只处理活跃的套接字。Fpm的这种处理模式大大简化了 PHP 的资源管理,使得在Fpm模式下不需要考虑并发导致的资源冲突。
marster 和 worker 通信

master 进程与 worker 进程之间不会直接进行通信,master 通过共享内存获取 worker 进程的信息,比如 worker 进程当前状态、已处理请求数等,master 进程通过发送信号的方式杀掉 worker 进程。

worker 请求处理

worker进程的工作周期

master 进程管理

woker 创建完成后,对请求的处理工作都会由 worker 进程来进行,而master 进程负责对worker进程的监控和管理。
FPM 可以同时监听多个端口,每个端口对应一个 worker pool。

Fpm 三种不同的进程管理方式:

static(静态模式)、dynamic(动态模式)、ondemand(按需模式)

这里主要说一下在 conf 配置中指定 pm,pm = dynamic。

这种模式比较常用,在 Fpm 启动时会初始化一定数量的 worker。运行期间如果 master 发现请求比较多,worker 处理不过来了则会 fork worker 进程,如果 master 发现闲着的 worker 太多了,则会杀掉一些 worker,避免占用过多资源
master通过这4个值来动态控制 worker 的数量

  • pm.start_servers 初始化一定数量的 worker
  • pm.min_spare_servers 最小 worker 数
  • pm.max_children 最大 worker 数
  • pm.max_spare_servers 空闲 worker 数
Socket

Nginx 服务器和 PHP-FPM 可以通过 TCP SocketUNIX Socket 两种方式实现

  • UNIX Socket 是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。这种方式需要在Nginx配置文件中填写PHP-FPM的pid文件位置,效率要比 TCP Socket 高。
  • TCP Socket 的优点是可以跨服务器,当Nginx和PHP-FPM不在同一台机器上时,只能使用这种方式。

FastCGI 协议

FastCGI 是一种协议,它是建立在 CGI/1.1 基础之上的,把 CGI/1.1 里面要传递的数据通过 FastCGI 协议定义的顺序和格式进行传递。整个 FastCGI 是二进制连续传递的。

具体内容就不细解了。

总结

整个 FPM 模式实际上是多进程模式,首先由 calling process 进程 fork 出 master 进程,master 进程会创建 Socket,然后 fork 出 worker 进程,worker 进程会在 accept 处阻塞等待,请求过来时,由其中一个worker 进程处理,按照 FastCGI 模式进行各阶段的读取,然后解析 PHP 并执行,最后按照 FastCGI 协议返回数据,继续进入 accept 处阻塞等待。另外,FPM 建立了计分板机制,可以关注全局和每个 woker 的工作情况,方便使用者监控。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:淡淡de盐

查看原文:SAPI php-fpm FastCGI原理介绍

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

503 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传