### [Laravel Octane 结合 Swoole 配置常驻内存请求复用](https://www.huociguo.com/article/168) **Published:** 2026-07-17T08:06:48 **Author:** 米了 **Excerpt:** Laravel Octane 通过 Swoole 扩展将应用实例常驻于内存,消除传统 PHP-FPM 模式下每个请求重复引导框架的开销。启用后需重点处理单例污染、静态属性残留与数据库连接复用三类问题,配合 octane:reload 平滑重 Laravel Octane 通过 Swoole 扩展将应用实例常驻于内存,消除传统 PHP-FPM 模式下每个请求重复引导框架的开销。启用后需重点处理单例污染、静态属性残留与数据库连接复用三类问题,配合 octane:reload 平滑重启与内存泄漏监控,可稳定支撑高并发场景,单机 QPS 通常可提升数倍至数十倍。 ![](https://api.huociguo.com/wp-content/uploads/2026/07/Laravel-Octane-Swoole%E5%B8%B8%E9%A9%BB%E5%86%85%E5%AD%98%E8%AF%B7%E6%B1%82%E5%A4%8D%E7%94%A8-%E5%B0%81%E9%9D%A2%E5%9B%BE-17080e918a-1.png "Laravel-Octane-Swoole常驻内存请求复用-封面图-17080e918a-1") ## **一、运行模型差异** 传统 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 完成: ```bash composer require laravel/octane php artisan octane:install --server=swoole ``` 安装命令会发布 config/octane.php 配置文件并注册服务提供者。验证 Swoole 扩展是否就绪: ```bash php -m | grep swoole php --ri swoole ``` ## **三、核心配置项** config/octane.php 中与 Swoole 相关的关键配置如下: ```php '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: ```php 'listeners' => [ // 请求事件与刷新操作的映射关系 ], 'flush' => [ // 每个请求结束后自动重置的服务列表 ], ``` ## **四、启动与进程管理** 开发环境启动命令: ```bash php artisan octane:start --server=swoole --host=0.0.0.0 --port=8000 ``` 生产环境推荐附加参数: ```bash php artisan octane:start \ --server=swoole \ --workers=8 \ --task-workers=4 \ --max-requests=1000 \ --port=8000 ``` 代码变更不会自动生效,这是常驻内存模式与传统模式的核心差异之一。开发阶段可使用 –watch 参数监听文件变更自动重载,该功能依赖 chokidar,需先执行 npm install。生产环境禁止使用 –watch,正确做法是部署流程末尾执行: ```bash php artisan octane:reload ``` 该命令向 Swoole 发送信号,Worker 进程处理完当前请求后逐个重启,加载新代码的同时不产生请求中断,实现零停机部署。 进程守护通常交由 Supervisor 完成,配置示例: ```ini [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 生命周期内持续存在,常见的自增计数器、数组累积型缓存会导致内存单调增长。排查手段: ```bash 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 方法简化并发调用: ```php 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 密集型接口收益最大。压测命令示例: ```bash wrk -t4 -c200 -d30s http://127.0.0.1:8000/api/dashboard ``` ## **八、部署注意事项** 前置 Nginx 反向代理仍是推荐架构,Nginx 负责 TLS 终止、静态资源、限流与访问日志,动态请求转发至 Octane: ```nginx 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%。 **Tags:** Laravel Octane, PHP 常驻内存, Swoole, 协程并发, 高性能 Laravel **Categories:** PHP教程 ---