Laravel Octane 通过 Swoole 扩展将应用实例常驻于内存,消除传统 PHP-FPM 模式下每个请求重复引导框架的开销。启用后需重点处理单例污染、静态属性残留与数据库连接复用三类问题,配合 octane:reload 平滑重启与内存泄漏监控,可稳定支撑高并发场景,单机 QPS 通常可提升数倍至数十倍。

一、运行模型差异
传统 PHP-FPM 模式中,每个请求经历完整生命周期:进程接收请求、加载 Composer 自动加载器、引导服务容器、注册服务提供者、执行路由匹配、处理请求、销毁全部状态。Laravel 框架本身的引导耗时在中小型项目中普遍占据 10 至 50 毫秒,高并发下成为主要瓶颈。
Octane 改变了这一模型。Swoole 以独立进程形式运行 HTTP 服务器,Worker 进程启动时完成一次框架引导,随后循环处理请求,应用实例、服务容器、已加载的类定义全部保留在内存中。请求到达时仅执行路由分发与业务逻辑,跳过重复的初始化阶段。
Swoole 同时提供协程支持,单个 Worker 内可并发挂起与恢复多个 IO 操作,数据库查询、Redis 读写、外部 HTTP 调用不再阻塞进程,同等硬件下可承载的连接数显著高于同步阻塞模型。
二、环境要求与安装
生产部署前需确认以下条件:
-
PHP 8.1 或更高版本,推荐 8.2 及以上
-
Swoole 扩展 5.x 系列,编译时启用 OpenSSL 与协程支持
-
Laravel 10 或更高版本
-
Linux 操作系统,Swoole 不支持 Windows 原生环境
安装 Octane 通过 Composer 完成:
composer require laravel/octane
php artisan octane:install --server=swoole安装命令会发布 config/octane.php 配置文件并注册服务提供者。验证 Swoole 扩展是否就绪:
php -m | grep swoole
php --ri swoole三、核心配置项
config/octane.php 中与 Swoole 相关的关键配置如下:
'swoole' => [
'options' => [
'worker_num' => env('OCTANE_WORKER_NUM', swoole_cpu_num()),
'task_worker_num' => env('OCTANE_TASK_WORKER_NUM', swoole_cpu_num()),
'max_request' => env('OCTANE_MAX_REQUEST', 1000),
'package_max_length' => 10 * 1024 * 1024,
'open_http2_protocol' => true,
],
],各项参数的实际作用:
-
worker_num:处理请求的 Worker 进程数量,通常设置为 CPU 核心数
-
task_worker_num:异步任务进程数量,处理通过 Octane::task 投递的耗时操作
-
max_request:单个 Worker 处理指定请求数后自动重启,这是对抗内存泄漏的第一道防线,生产环境建议 500 至 2000 之间
-
package_max_length:允许的最大请求体大小,涉及大文件上传时需同步调整
监听配置位于 octane 配置顶层,支持多端口与 Unix Socket:
'listeners' => [
// 请求事件与刷新操作的映射关系
],
'flush' => [
// 每个请求结束后自动重置的服务列表
],四、启动与进程管理
开发环境启动命令:
php artisan octane:start --server=swoole --host=0.0.0.0 --port=8000生产环境推荐附加参数:
php artisan octane:start \
--server=swoole \
--workers=8 \
--task-workers=4 \
--max-requests=1000 \
--port=8000代码变更不会自动生效,这是常驻内存模式与传统模式的核心差异之一。开发阶段可使用 –watch 参数监听文件变更自动重载,该功能依赖 chokidar,需先执行 npm install。生产环境禁止使用 –watch,正确做法是部署流程末尾执行:
php artisan octane:reload该命令向 Swoole 发送信号,Worker 进程处理完当前请求后逐个重启,加载新代码的同时不产生请求中断,实现零停机部署。
进程守护通常交由 Supervisor 完成,配置示例:
[program:octane]
command=php /var/www/html/artisan octane:start --server=swoole --port=8000
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/log/octane.log五、常驻内存的三大陷阱
1、单例污染
服务容器中的 singleton 在首个请求解析后长期存活。若某单例在构造或方法中保存了请求级数据(当前用户、租户 ID、请求参数),后续请求将读取到残留数据,造成串号。规避方式包括:
-
请求级状态改为通过容器在请求内绑定 instance 而非 singleton
-
将需逐请求重置的服务加入 octane 配置的 flush 数组
-
监听器中处理 RequestReceived 事件时显式重置关键状态
2、静态属性与全局变量
静态属性在 Worker 生命周期内持续存在,常见的自增计数器、数组累积型缓存会导致内存单调增长。排查手段:
php artisan octane:start --max-requests=1将 max-request 临时设为 1 后观察内存曲线,若仍持续增长则问题出在引导阶段;逐步调大数值可定位泄漏发生在请求处理阶段。同时可借助 Swoole 的 stats 接口或 gc_status() 定期输出内存占用。
3、数据库与 Redis 连接复用
长连接不会因请求结束而释放。MySQL 服务端 wait_timeout 到期后会单方面断开连接,下一次查询触发 MySQL server has gone away 错误。标准解决方案:
-
config/database.php 中启用持久连接并配置合理的连接池参数
-
Octane 内置监听会在请求结束后自动断开并重建失效连接,确保 config/octane.php 的 flush 与 listeners 配置未被误删
-
业务代码避免在构造函数中执行查询,防止连接在引导期建立后闲置超时
六、协程并发与请求复用实践
Swoole 协程允许在单个请求内并发执行多个 IO 操作。Octane 提供 concurrently 方法简化并发调用:
use Laravel\Octane\Facades\Octane;
[$users, $orders, $stats] = Octane::concurrently([
fn () => $userService->list($tenantId),
fn () => $orderService->recent($tenantId),
fn () => $statService->dashboard($tenantId),
], 10000); // 超时毫秒数三个查询在不同协程中并行执行,总耗时约等于最慢的一项,而非三者之和。适用前提是各操作相互独立,且数据库连接池容量足以支撑并发数。
协程环境下需注意:
-
启用协程后 Laravel 的 DB 与 Redis 客户端需使用 Swoole 协程兼容驱动,Octane 已处理该适配
-
文件锁、全局状态在协程间不再安全,共享资源改用 Channel 或原子计数器
-
同步阻塞函数(如部分未适配的扩展调用)会阻塞整个 Worker,压测时需覆盖到
七、性能压测对比
基准测试环境:4 核 8G 云主机、PHP 8.3、Laravel 11、简单查询接口。
|
运行模式 |
平均 QPS |
P99 延迟 |
|---|---|---|
|
Nginx + PHP-FPM |
约 850 |
120ms |
|
Octane + Swoole(关闭协程) |
约 4200 |
28ms |
|
Octane + Swoole(启用协程并发) |
约 9000 |
15ms |
实际提升幅度取决于业务中框架引导耗时与 IO 等待的占比。CPU 密集型业务提升有限,IO 密集型接口收益最大。压测命令示例:
wrk -t4 -c200 -d30s http://127.0.0.1:8000/api/dashboard八、部署注意事项
前置 Nginx 反向代理仍是推荐架构,Nginx 负责 TLS 终止、静态资源、限流与访问日志,动态请求转发至 Octane:
location / {
try_files $uri @octane;
}
location @octane {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}监控层面需关注三项指标:Worker 进程常驻内存走势、单 Worker 请求计数与重启频率、协程并发数峰值。Prometheus 可通过 Swoole 暴露的指标接口接入,告警阈值建议设置为内存较启动基线上涨 50%。

