本文目录导读:

对于 Laravel 应用的零停机部署,直接使用负载均衡并不是零停机的充要条件,而是实现零停机的基础设施组件,它们的关系是:负载均衡器负责流量切换,而 Laravel 应用本身需要配合特定的部署策略才能实现真正的零停机。
简单回答是:是的,但光有负载均衡不够,需要结合「蓝绿部署」或「滚动更新」策略。
下面详细解释如何用负载均衡实现 Laravel 的零停机部署:
核心原理:负载均衡 + 健康检查
零停机部署的本质是:在更新代码时,不让任何用户的请求碰到正在更新的旧代码或未准备好的新代码。
负载均衡器(如 Nginx、AWS ALB、HAProxy)通过以下方式实现:
- 双/多服务器池:将流量分发到多台后端应用服务器(运行 Laravel)。
- 健康检查:在部署新版本时,先让新服务器通过健康检查,再将流量切过去;同时从负载池中摘掉旧服务器。
- 会话保持(可选):如果使用文件 Session,需要配置负载均衡器的 sticky session(会话保持),确保同一用户始终打到同一台服务器。更推荐使用 Redis/Memcached 集中管理 Session,这样就不依赖负载均衡的会话保持。
两种常见的零停机部署架构
方案 A:蓝绿部署(推荐用于关键生产环境)
你需要两套完全独立的环境(蓝环境、绿环境),通常各有多台服务器,前面挂负载均衡器。
步骤:
- 当前:负载均衡器将所有流量导向蓝环境(旧版本)。
- 准备新版本:在绿环境上部署新代码、运行
composer install、migrations、artisan optimize等。此时绿环境对用户不可见。 - 切换流量:修改负载均衡器的配置,将流量 100% 切换到绿环境。
- 验证:检查绿环境运行正常后,下线蓝环境。
- 回滚:如果出问题,直接把流量切回蓝环境。
优点:切换瞬间完成,几乎没有风险。
缺点:需要两倍的服务器资源。
方案 B:滚动更新(更省资源,需要更精细配置)
你有一个负载均衡器,后面挂 N 台服务器,3 台服务器(Web1、Web2、Web3)。
步骤:
- 在负载均衡器上将 Web1 从服务池中摘除(drain,不中断现有连接,但不接收新请求)。
- 等待几秒,确保 Web1 上没有活跃请求。
- 在 Web1 上部署新代码(更新文件、运行迁移、清除缓存等)。
- 将 Web1 重新加入服务池,等待健康检查通过,开始接收流量。
- 依次对 Web2、Web3 重复上述步骤。
需要注意的坑:
- 数据库迁移:Laravel 的迁移是棘手的,如果新代码依赖于新增的字段,而旧代码还没有该字段,新旧代码同时运行时可能出错,你需要后向兼容的迁移:先添加新字段(允许 NULL),部署完所有服务后,再运行一个脚本去填充数据并修改表结构。
- 缓存/配置:
php artisan config:cache必须在部署后执行,每台服务器部署完后都要清掉 OPcache 和 Laravel 缓存,否则新旧代码混杂。 - 队列:如果使用了 Horizon 或队列,需要确保所有旧的队列 Worker 在处理完旧任务后,再启动新 Worker,最稳妥的做法是先停止旧 Worker,部署代码,再启动新 Worker。
Laravel 具体需要配合做的关键操作
光靠负载均衡切换流量是不够的,Laravel 层也需要准备:
- 数据库迁移:
- 不要在新版本发布时直接运行
php artisan migrate(尤其是在滚动更新中)。 - 最佳实践:将迁移放在部署之前单独执行,新代码兼容旧表结构,旧代码忽略新字段。
- 不要在新版本发布时直接运行
- 优化命令:
- 部署脚本中需要执行:
php artisan down --retry=60 # 如果你的负载均衡没有摘除服务器的功能,可以用维护模式,但通常不推荐在生产用维护模式做零停机 # 蓝绿部署 不需要 down 命令,滚动更新需要在摘除服务器后执行 php artisan config:cache php artisan route:cache php artisan view:cache composer install --no-dev --optimize-autoloader
- 部署脚本中需要执行:
- Session 和缓存:
- 使用 Redis 或数据库存储 Session,而不是文件,否则流量切换后,用户会丢失登录态。
- Cache 和 Cache Tags 也要使用集中式缓存(Redis/Memcached),保证所有服务器共享缓存。
- 维护模式(Laravel 8+ 的改进):
- 如果无法避免小中断,Laravel 的
php artisan down支持--retry参数,可以让 nginx 返回 503,并告知浏览器 60 秒后重试,这种方法适用于非常短时间的停机(几秒内),但对于真正的零停机部署,最好不用维护模式。
- 如果无法避免小中断,Laravel 的
推荐的实践方案(基于成本与效果)
- 小项目 / 低流量:
- 使用 Enoy 或 Laravel Forge 这类部署工具,它们内置了零停机部署(本质是同步文件到临时目录,然后切换符号链接 + 加载 Opcache 刷新)。
- 不需要负载均衡,只需要一个 Nginx 符号链接切换。
- 中大型项目 / 高流量:
- AWS:使用 ALB (Application Load Balancer) + Auto Scaling Group,部署时创建一个新的启动配置,滚动更新机器组。
- Kubernetes:使用 Deployment + Service,K8s 自带滚动更新和健康检查,完全零停机。
- 自建服务器:使用 Nginx + 最少两台服务器,配置
upstream并在部署时逐个摘除。
负载均衡是实现 Laravel 零停机部署的必备条件之一,但不是全部。
你需要:
- 负载均衡器 + 健康检查。
- 蓝绿部署或滚动更新策略。
- Laravel 层面的后向兼容迁移、集中化 Session/Cache、正确的部署脚本。
如果只是简单地将多台服务器挂在同一个负载均衡后面,然后直接 git pull,一定会有停机时间(因为新旧代码不一致、迁移冲突、缓存不一致),正确的做法是:先用负载均衡摘除服务器,再更新,再放回。