VPS 上的 PHP 模式:mod_php vs FastCGI vs PHP-FPM — 完整指南
PHP 为互联网上超过 80% 的网站提供支持,但最容易被忽视的性能决策之一是选择正确的 PHP 执行模式。选择错误的模式,你会面临缓慢的加载时间、过度的 RAM 消耗和流量激增时的服务器崩溃。选择正确的模式,你的应用程序可以轻松扩展,即使在高并发负载下也是如此。
本指南详细介绍了三种主要的 PHP 执行模式 — mod_php、FastCGI 和 PHP-FPM — 包括真实的性能背景、配置示例和针对不同用例的明确建议。无论你运行的是个人博客还是高流量电子商务平台,理解这些模式是充分利用服务器环境的基础。
目录
- 什么是 PHP 执行模式?
- mod_php — 经典 Apache 模块
- FastCGI — 将 PHP 与 Web 服务器解耦
- PHP-FPM — 高性能的现代标准
- 并排比较
- 如何在 VPS 上设置 PHP-FPM (Ubuntu/Debian)
- PHP-FPM 与 Nginx
- PHP-FPM 与 Apache
- 生产环境中的 PHP-FPM 池调优
- 你应该选择哪种 PHP 模式?
- 结论
什么是 PHP 执行模式? {#what-are-php-execution-modes}
PHP 执行模式定义了你的 Web 服务器如何解释和运行 PHP 脚本。它确定了 Web 服务器进程(Apache、Nginx、LiteSpeed)和 PHP 解释器之间的关系 — 具体来说,它们是否共享同一进程、通过协议通信,还是作为完全独立的托管服务运行。
三种主要模式是:
| 模式 | 架构 | 最适合 |
|---|---|---|
| mod_php | PHP 嵌入在 Apache 中 | 简单的共享环境 |
| FastCGI | PHP 作为独立进程 | 中等流量网站 |
| PHP-FPM | 托管 PHP 进程池 | 高流量、生产应用 |
选择正确的模式直接影响内存使用、请求吞吐量、隔离和可扩展性。在 VPS 主机环境中,资源是专用的且可配置的,你可以完全自由地实现最适合你工作负载的任何模式。
mod_php — 经典 Apache 模块 {#mod_php}
什么是 mod_php?
mod_php 是一个 Apache 模块,它将 PHP 解释器直接嵌入到 Apache Web 服务器进程中。这是运行 PHP 最古老且历史上最常见的方法。
mod_php 如何工作
当 Apache 收到对 .php 文件的请求时,它在内部处理执行 — 不会生成外部进程,不会发生套接字通信。PHP 存在于 Apache 内部。
Apache Process (PID 1234)
├── PHP Interpreter (loaded once)
├── Request 1 → PHP execution
├── Request 2 → PHP execution
└── Request 3 → PHP execution性能特征
对于低流量网站和开发环境,mod_php 的性能是充分的。因为 PHP 已经加载到 Apache 的内存中,每个请求没有进程生成开销。
但是,这种架构有一个关键缺陷:每个 Apache 工作进程都在内存中携带完整的 PHP 解释器,无论它是在提供 PHP 文件还是提供静态资产(如图像或 CSS 文件)。
mod_php 的缺点
- 高内存消耗:每个 Apache 工作进程(即使是提供静态文件的进程)都在 RAM 中保存完整的 PHP 运行时。
- 无每个站点的隔离:所有虚拟主机共享同一 PHP 进程和用户上下文,这在多租户服务器上是一个安全问题。
- 配置灵活性有限:你无法为不同的虚拟主机运行不同的 PHP 版本,除非进行重大的变通。
- 与 Nginx 不兼容:mod_php 仅限于 Apache;它不能与 Nginx 或 LiteSpeed 一起使用。
- 在负载下的可扩展性差:在高并发下,内存耗尽成为真正的风险。
何时使用 mod_php
- 本地开发环境
- 非常低流量的个人网站
- 无法重新配置的遗留应用程序
FastCGI — 将 PHP 与 Web 服务器解耦 {#fastcgi}
什么是 FastCGI?
FastCGI 是一种协议,允许 Web 服务器与外部 PHP 进程通信,而不是将 PHP 嵌入到自身中。这是相对于 mod_php 的重大架构改进。
FastCGI 如何工作
Web 服务器(Apache 或 Nginx)通过 Unix 套接字或 TCP 端口将 PHP 请求传递给持久的 FastCGI 进程。PHP 进程处理执行并返回结果。
Apache Process PHP Process
│ │
├─ Request 1 ────────→ ├─ PHP execution
├─ Request 2 ────────→ ├─ PHP execution
└─ Request 3 ────────→ └─ PHP execution
(via Unix socket or TCP)这里的关键词是持久的:与原始协议 CGI 不同,FastCGI 进程在请求之间保持活动,消除了为每个单独请求生成新进程的开销。
性能特征
与 mod_php 相比,FastCGI 显著降低了内存开销,因为静态文件请求完全由 Web 服务器处理,不涉及 PHP。PHP 进程仅在真正需要时调用。
FastCGI 的缺点
- 配置复杂性:与 mod_php 相比需要额外的设置,包括套接字或端口配置。
- 进程管理有限:基本 FastCGI 缺乏生产环境所需的高级池管理功能。
- 被 PHP-FPM 取代:在大多数现代部署中,PHP-FPM(基于 FastCGI 构建)优于基本 FastCGI 实现。
何时使用 FastCGI
- 中等流量网站
- PHP-FPM 不可用的环境
- 从 mod_php 迁移的过渡设置
PHP-FPM — 高性能的现代标准 {#php-fpm}
什么是 PHP-FPM?
PHP-FPM(FastCGI 进程管理器)是 FastCGI 协议的高级、功能丰富的实现。它是在生产环境中运行 PHP 的事实标准,也是任何严肃 Web 应用程序的推荐模式。
PHP-FPM 如何工作
PHP-FPM 管理一个PHP 工作进程池。Web 服务器通过 Unix 套接字或 TCP 连接将 PHP 请求转发给 PHP-FPM。PHP-FPM 根据当前流量动态管理活跃工作进程的数量,在负载下启动新工作进程,在安静期间释放它们。
Nginx Process PHP-FPM Master
│ │
├─ Request 1 ────────→ ├─ Worker 1 (PHP execution)
├─ Request 2 ────────→ ├─ Worker 2 (PHP execution)
├─ Request 3 ────────→ ├─ Worker 3 (PHP execution)
└─ Request 4 ────────→ └─ Worker 4 (PHP execution)
(via Unix socket) (dynamic scaling)PHP-FPM 的主要优势
#### 1. 动态进程管理
PHP-FPM 支持多种进程管理策略:
- static:固定数量的工作进程(可预测,适合高流量)
- dynamic:工作进程根据需求在最小值和最大值之间扩展
- ondemand:工作进程仅在请求到达时生成(对低流量内存高效)
#### 2. 每个池的配置
每个应用程序或虚拟主机都可以有自己的 PHP-FPM 池,具有独立的设置:
- 独立的 Unix 用户/组(改进的安全隔离)
- 每个池的不同 PHP 版本
- 每个应用程序的自定义 php.ini 值
- 单独的资源限制
#### 3. 慢请求日志
PHP-FPM 可以记录超过定义的执行时间阈值的请求,这对于识别性能瓶颈非常宝贵。
#### 4. 资源效率
因为 PHP 进程与 Web 服务器分开管理,静态资产的提供没有任何 PHP 开销。内存仅由活跃的 PHP 工作进程消耗。
#### 5. 兼容性
PHP-FPM 与 Nginx、Apache(通过 mod_proxy_fcgi)和 LiteSpeed 无缝协作。与 Nginx 或 LiteSpeed 结合时,性能提升是巨大的 — 与 Apache 的 mod_php 相比,在并发负载下通常快 5–10 倍。
并排比较 {#comparison}
| 功能 | mod_php | FastCGI | PHP-FPM |
|---|---|---|---|
| 架构 | 嵌入在 Apache 中 | 外部进程 | 托管进程池 |
| 内存效率 | 低 | 中等 | 高 |
| 静态文件开销 | 高 | 低 | 低 |
| 并发请求处理 | 差 | 好 | 优秀 |
| 每个站点的 PHP 版本 | 否 | 有限 | 是 |
| 安全隔离 | 差 | 中等 | 优秀 |
| Nginx 兼容性 | 否 | 是 | 是 |
| 配置复杂性 | 低 | 中等 | 中等 |
| 生产就绪 | 否 | 部分 | 是 |
| 慢请求日志 | 否 | 否 | 是 |
如何在 VPS 上设置 PHP-FPM (Ubuntu/Debian) {#setup}
以下说明适用于 Ubuntu 22.04 LTS 和 Debian 11/12。如果你在 VPS 主机计划上运行你的应用程序,你将拥有完整的 root 访问权限来执行这些命令。
步骤 1:更新你的系统并安装 PHP-FPM
sudo apt update && sudo apt upgrade -y
sudo apt install php-fpm -y要安装特定的 PHP 版本(例如 PHP 8.2):
sudo apt install php8.2-fpm -y
步骤 2:验证 PHP-FPM 正在运行
sudo systemctl status php-fpm
你应该在输出中看到 active (running)。如果没有,启动并启用它:
sudo systemctl start php-fpm
sudo systemctl enable php-fpm步骤 3:确认套接字路径
PHP-FPM 通过 Unix 套接字通信。验证其位置:
sudo find /run -name "php*.sock" -type s
PHP-FPM 与 Nginx {#nginx}
Nginx 是与 PHP-FPM 配对最常见的 Web 服务器,原因充分 — Nginx 的事件驱动、非阻塞架构完美补充了 PHP-FPM 的进程池模型。
安装 Nginx
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx配置 Nginx 服务器块
编辑你的站点配置文件:
sudo nano /etc/nginx/sites-available/example.com
添加以下配置:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
location ~ /.ht {
deny all;
}
}启用站点并重启 Nginx
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxPHP-FPM 与 Apache {#apache}
如果你更喜欢 Apache — 或者如果你的应用程序依赖于 .htaccess 文件 — 你仍然可以通过 Apache 的 mod_proxy_fcgi 模块使用 PHP-FPM。
启用所需的 Apache 模块
sudo a2enmod proxy
sudo a2enmod proxy_fcgi
sudo systemctl restart apache2配置 Apache 虚拟主机
sudo nano /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
<FilesMatch .php$>
SetHandler "proxy:unix:/run/php/php-fpm.sock|fcgi://localhost"
</FilesMatch>
<Directory /var/www/example.com>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>启用站点并重启 Apache
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl restart apache2生产环境中的 PHP-FPM 池调优 {#tuning}
默认的 PHP-FPM 池配置是保守的,适合开发。对于生产工作负载,你应该根据服务器的可用 RAM 和预期流量调优池设置。
定位池配置文件
sudo nano /etc/php/8.2/fpm/pool.d/www.conf
关键参数调优
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 1000
request_terminate_timeout = 60
slowlog = /var/log/php-fpm/slow.log
request_slowlog_timeout = 5计算 pm.max_children
动态环境的实用公式:
pm.max_children = (Total Available RAM - OS/Other Services) / Average PHP Process Size
要找到平均 PHP 进程大小:
ps aux | grep php-fpm | grep -v grep | awk '{sum+=$6} END {print sum/NR " KB"}'
在典型的 WordPress 网站上,每个 PHP-FPM 工作进程消耗大约 30–60 MB。在具有 2 GB RAM 的 VPS 上(为 OS 开销后留下约 1.5 GB),你可以安全地运行 25–50 个工作进程。
应用更改
sudo systemctl restart php-fpm
