认识FastCGI以及优化

关于 FastCGI 的深入理解

经常听到 FastCGI 这个词,感觉很高深。自己去了解后才发现,它其实就是我们每天都在用的老朋友------php-fpm

php-fpm 的全称是 FastCGI Process Manager,顾名思义,它就是 FastCGI 协议的一个进程管理器。

一、前世:CGI 的困境

要理解 FastCGI,得先看它的前身 CGI

CGI 的工作流程很简单:

  1. 浏览器请求一个 PHP 页面。

  2. Web 服务器(如 Apache)收到请求。

  3. 服务器创建一个全新的系统进程来调用 PHP 解释器。

  4. PHP 解释器执行 .php 文件,生成 HTML。

  5. PHP 进程将结果返回给服务器。

  6. 服务器将 HTML 发回浏览器。

  7. PHP 进程立即退出。

CGI 的困境: 每个请求都要经历一次"创建进程 -> 销毁进程"的循环。如果瞬间有1000个并发请求,服务器就需要创建和销毁1000个进程,巨大的开销严重限制了服务器性能。

二、今生:FastCGI 的核心思想

为了解决 CGI 的性能瓶颈,FastCGI 诞生了。它的核心改进是:使用常驻的进程池来处理请求

FastCGI 的四个核心思想:

  • 进程常驻:进程启动后一直运行,处理完请求也不退出,等待下一个任务。

  • 进程池:启动一组进程,共同处理并发请求。

  • 解耦:Web 服务器(如 Nginx)和应用语言(如 PHP)彻底分离,通过 FastCGI 协议通信。

  • 网络通信:通过 Socket(本地或网络)进行通信,部署更灵活。

三、我们熟悉的工作流程(Nginx + PHP-FPM)

这正是我们在 Linux 上搭建网站时,Nginx 与 PHP 协作的实际流程:

  1. 用户请求:浏览器访问一个 PHP 页面。

  2. Nginx 接收 :Nginx 发现是 .php 请求,便准备交给 PHP-FPM 处理。

  3. 转发请求 :Nginx 将请求信息按 FastCGI 协议打包,通过 Socket 发送给 PHP-FPM。

  4. PHP-FPM 处理:PHP-FPM 的主进程接收请求,从进程池中分配一个空闲的 Worker 进程来执行 PHP 文件并生成 HTML。

  5. 返回响应 :Worker 将结果按 FastCGI 协议打包,返回给 Nginx。

  6. Nginx 响应:Nginx 将 HTML 发送给用户浏览器。

  7. 进程复用 :Worker 进程不退出,清理后回到进程池,等待下一个请求。

四、深入 FastCGI 协议

这个"打包"是 FastCGI 协议在起作用。它是一个结构化的、基于记录的二进制协议

所有的通信都被分割成一个个的记录 。每个记录都包含一个记录头和可变长度的内容。

记录头包含以下关键信息:

  • 版本:标识 FastCGI 协议版本。

  • 类型:定义了记录的目的,是协议的核心。主要包括:

    • BEGIN_REQUEST:标志着新请求的开始。

    • PARAMS:用于传输环境变量和请求元数据。

    • STDIN:用于传输 HTTP 请求体(POST 数据)。

    • STDOUT:用于传输应用生成的响应体。

    • STDERR:用于传输错误日志。

    • END_REQUEST:标志着请求处理完毕。

  • 请求ID:用于复用同一个连接处理多个请求。

  • 内容长度:指示后面跟着的内容数据的长度。

协议层面的完整通信流程:

  1. 请求开始 :Nginx 发送一个 BEGIN_REQUEST 记录。

  2. 传递元数据 :Nginx 发送一个或多个 PARAMS 记录,并以一个长度为0的 PARAMS 记录作为结束标志。

  3. 传递请求体 :Nginx 通过一个或多个 STDIN 记录发送 POST 数据,同样以长度为0的记录标志结束。

  4. 处理请求:PHP-FPM 的 Worker 进程开始执行 PHP 脚本。

  5. 返回响应 :Worker 通过 STDOUT 记录发回响应,通过 STDERR 记录发回错误日志,最后发送 END_REQUEST 记录结束整个请求。

五、性能优化实战

1. 进程池管理 (配置目录:/etc/php/8.1/fpm/pool.d/www.conf)

我们可以修改进程管理器模式来优化性能:

  • static 模式

    • 描述:进程数量固定不变。

    • 优点:性能最高,无进程管理开销。

    • 缺点:内存占用固定且高。

    • 适用:高流量、高性能服务器。

  • dynamic 模式 (最常用)

    • 描述:动态调整进程数。

    • 关键参数

      • pm.max_children:进程池最大允许的进程数。

      • pm.start_servers:启动时创建的进程数。

      • pm.min_spare_servers:保证空闲的最少进程数。

      • pm.max_spare_servers:允许空闲的最大进程数。

    • 优点:在性能和资源间取得平衡。

    • 适用:绝大多数通用生产环境。

  • ondemand 模式

    • 描述:有请求时才创建进程,空闲时自动杀死。

    • 优点:极度节省内存。

    • 缺点:新请求到来时有创建延迟。

    • 适用:内存紧张、访问量极低的环境。

2. 慢日志配置 这是一个极其重要的调试功能。

  • 作用:记录执行时间超过设定阈值的 PHP 脚本。

  • 关键配置

    • request_slowlog_timeout:定义"慢"的阈值(如10秒)。

    • slowlog:指定慢日志文件路径。

  • 价值:当请求执行过慢时,会记录完整的 PHP 函数调用栈,对于定位数据库慢查询、死锁或低效代码至关重要。

3. Socket 通信方式

  • Unix Domain Socket

    • 路径示例unix:/var/run/php/php8.1-fpm.sock

    • 原理:通过文件系统上的特殊 socket 文件进行通信,完全在内核中完成。

    • 优点:速度更快,开销更小。

    • 缺点:只能用于同一台服务器上的进程间通信。

    • 适用场景Web服务器和PHP应用部署在同一台机器上时的首选。

  • TCP Socket

    • 路径示例127.0.0.1:9000

    • 原理:通过网络协议栈进行通信。

    • 优点:更灵活,可以跨服务器部署;更容易被网络监控工具分析。

    • 缺点:有网络协议栈的开销,速度稍慢于 UDS。

    • 适用场景:跨服务器部署,或需要通过网络工具进行调试时。


总结

正是 Nginx + PHP-FPM (FastCGI) 这套组合,以其高性能、高稳定性、资源隔离和架构灵活性,成为了当今运行 PHP 应用最主流和推荐的方式。

我们不是在学习一个新概念,只是在为早已熟练使用的技术,正名而已。

相关推荐
摘星编程3 个月前
Nginx 502 Bad Gateway:从 upstream 日志到 FastCGI 超时复盘
网络·nginx·gateway·php-fpm·fastcgi
加油,旭杏1 年前
【中间件学习】fastCG介绍和使用
学习·nginx·fastcgi
Jay 172 年前
Ctfshow web入门 代码审计篇 web301-web310 详细题解 全
nginx·web安全·php·代码审计·sql注入·反序列化·fastcgi