蓝绿部署需隔离端口、状态文件、日志路径及配置缓存;octane:reload 不生效因 swoole worker 固化代码路径,不感知 symlink 变更;nginx 切流抖动源于未等新实例 warmup 完成,须配健康检查与预热验证。

做不到真正“零停机”,但能压到毫秒级中断——关键不在 Laravel 本身,而在部署架构和进程管理方式。
为什么 octane:reload 不生效?
因为 Swoole worker 进程启动后会把当前目录的代码、.env、甚至 Composer autoloader 映射进内存,octane:reload 只是重启 worker,不重新加载文件系统路径。符号链接切换后,旧进程仍读取原路径的代码快照。
- 现象:改了
routes/web.php或 Model,octane:reload后请求仍走旧逻辑 - 根本原因:Swoole 的
worker_start阶段已固化代码路径,不感知 symlink 变更 - 验证方法:在新代码里加
dd(__DIR__),看输出是否还是旧 release 目录
蓝绿部署必须改哪几处?
核心是让两套 Octane 实例互不干扰:不同端口、不同状态文件、不同日志路径。不能只改 --port,否则 octane:stop 会误杀另一组进程。
- 新增自定义命令
Octane:StartOctane,继承StartCommand,重写$serverStateFile路径(如/var/run/octane-blue.state) - Nginx upstream 必须用明确端口区分:
server 127.0.0.1:8001;和server 127.0.0.1:8002; - 启动时加
--no-interaction --quiet,避免交互阻塞自动化脚本 - 务必禁用
supervisord或 systemd 对 Octane 的自动重启,否则蓝绿切换会被覆盖
nginx reload 为什么还会抖动?
不是 reload 本身慢,而是上游服务未就绪就切流。Nginx 默认不等后端健康就转发,导致首几个请求打到刚启动、尚未完成 warmup 的新 Octane 实例上,返回 502 或超时。
- 解决方案:在 upstream 块中启用健康检查 +
max_fails=1 fail_timeout=10s - Octane 启动后需预热:用
curl -I http://127.0.0.1:8001/health检查返回 200 再 reload nginx - 避免用
proxy_next_upstream error timeout等兜底策略代替主动健康检测,它只缓解不根治
最容易被忽略的是 .env 和配置缓存的时效性——蓝绿两套实例必须各自运行 config:cache,不能共用一份缓存文件,否则新实例可能读到旧环境变量。











