本文目录导读:

- 方案一:前置 Nginx + 动态增加 PHP-FPM 进程数(最常用)
- 方案二:水平扩容(增加应用服务器节点)
- 方案三:使用 Swoole / Workerman 常驻内存模式(架构级优化)
- 方案四:突发限流 + 异步处理(“假”扩容,真保护)
- 根据业务场景选择
“PHP 突发扩容”通常指在流量高峰(如秒杀、突发活动)时,快速提升 PHP 应用的并发处理能力,防止服务器崩溃。
PHP 本身是阻塞式、单进程处理的语言(传统的 mod_php 模式),突发扩容的核心逻辑是:增加 PHP 进程数量 + 前置缓冲区/队列。
以下是针对 PHP 突发扩容的 4 种主流实战方案,按推荐程度排列:
前置 Nginx + 动态增加 PHP-FPM 进程数(最常用)
这是基于 php-fpm(FastCGI 进程管理器)的标准模式,突发扩容的核心是快速调整 php-fpm 的进程池参数。
操作步骤:
-
修改
php-fpm.conf或对应池配置(/etc/php/8.x/fpm/pool.d/www.conf):; 动态进程管理模式(推荐) pm = dynamic ; 突发扩容时,临时调大以下三个值: pm.max_children = 200 ; 最大子进程数(核心扩容点,原来是50可临时调至200) pm.start_servers = 100 ; 启动时进程数 pm.min_spare_servers = 80 ; 最小空闲进程数(保持预热) pm.max_spare_servers = 150; 最大空闲进程数 ; 并发连接数相关 pm.max_requests = 500 ; 每个进程处理500次请求后重启(防止内存泄漏)
-
立即生效(无需重启 Nginx):
# 重新加载 PHP-FPM 配置(平滑扩容) kill -USR2 $(cat /var/run/php-fpm.pid) # 或 systemctl reload php8.x-fpm
-
监控并扩容服务器资源(CPU/内存):
max_children不能超出服务器内存极限,假设每个 PHP 进程占 30MB,200 个进程需 6GB 内存。
优点: 延迟极低,配置后立即生效。
缺点: 依赖服务器物理资源(CPU/RAM),单机扩容有上限。
水平扩容(增加应用服务器节点)
如果单台机器进程数调整到极限(500 进程 撑爆了内存),就必须增加服务器数量。
架构:
用户 -> 负载均衡器(LVS/Nginx/HAProxy)
-> PHP App Server 1 (php-fpm + Nginx)
-> PHP App Server 2 (新加, 突发扩容)
-> PHP App Server 3 (新加)
快速突发扩容方式(尤其是云环境):
- 制作镜像/使用自定义 AMI: 提前将 PHP 应用和环境打好镜像。
- 云 API 一键扩容(5 分钟内完成):
- AWS Auto Scaling: 设置
CPU > 70%自动加机器。 - 阿里云 ESS(弹性伸缩): 配置伸缩组,点一下“手动扩容”或设置定时任务(如活动前 30 分钟自动加 5 台)。
- Kubernetes HPA: 如果容器化,执行
kubectl scale deployment php-app --replicas=20。
- AWS Auto Scaling: 设置
优点: 打破单机瓶颈,扩容能力无限(理论)。
缺点: 需要运维自动化支持,新机器启动需要几秒钟到几分钟,需要解决 Session 共享(用 Redis)和文件同步(用 NFS/Oss)问题。
使用 Swoole / Workerman 常驻内存模式(架构级优化)
传统 PHP-FPM 每个请求都重载 PHP 环境和框架(如 Laravel 启动耗时 ~50ms),导致突发时 CPU 很快跑满。
改造方案: 将 PHP 从 CGI 模式改为常驻内存协程模式(类似 Node.js)。
- Swoole(
Swoole\Http\Server):启动后内存常驻,请求到来直接回调,无需反复创建进程。 - Workerman:类似。
突发扩容操作:
// 原本 10 个 Worker 进程,突发时改为 50 个
$server = new Swoole\Http\Server("0.0.0.0", 9501);
// 设置为 50 个 worker 进程(突发时)
$server->set([
'worker_num' => 50,
'max_request' => 10000,
]);
$server->start();
效果: 单个进程可以同时处理成千上万并发(基于 IO 多路复用和协程),对服务器资源消耗远小于 FPM。
优点: 并发能力提升 10~100 倍,单机就能抗住较大流量。
缺点: 代码不兼容传统 PHP(需要修改),有内存泄漏风险。
突发限流 + 异步处理(“假”扩容,真保护)
当突发流量超过服务器上限时,强行扩容可能会导致依赖的数据库/Redis 先崩溃。优先保护系统可用性:
-
队列消峰(Redis + Worker):
- 用户请求立刻返回“排队中”,任务写入 Redis List(
RPUSH task_queue ...)。 - 单独 PHP CLI 进程(Worker)从队列中消费(
BLPOP),处理完成后通知用户。 - 突发扩容: 启动更多 Worker 进程(
nohup php worker.php &)。
# 突发时,启动 20 个后台 Worker 同时处理 for i in {1..20}; do nohup php /var/www/worker.php >> /tmp/worker.log 2>&1 & done - 用户请求立刻返回“排队中”,任务写入 Redis List(
-
Nginx 限流: 在 Nginx 层配置
limit_req_zone,对 IP 做速率限制,防止单个用户打死服务。
根据业务场景选择
| 场景 | 推荐方案 | 备注 |
|---|---|---|
| 常规突发流量(10倍内) | 动态调大 FPM max_children |
最快速,改配置即可 |
| 大型活动(100倍流量) | 水平扩容(云 API / K8s) | 需要基础设施自动化 |
| 秒杀/高并发 API | 升级 Swoole 常驻内存 | 架构改造,从根本提升 |
| 数据库先扛不住了 | 异步队列 + 限流 | 保命策略,比硬扩容更优 |
紧急操作流程(纯运维 5 分钟版):
- 登录服务器,执行
pkill -USR2 php-fpm(如果配置了pm.max_children足够大)。 - 如果还不行,上云控制台:把服务器从 4 核 8G 热升级到 16 核 32G(大部分云平台支持不关机升级)。
- 再不行,登录负载均衡,手动添加一台新的实例(用已有快照创建)。
- 同时开启 Nginx 限流,防止雪崩。
最后提醒: PHP 突发扩容不能只靠 PHP 本身,一定要关注下游:MySQL 连接池、Redis 带宽、Nginx 连接数是否也同步扩容了。