You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel多服务器部署如何仅单台执行migrate(类似调度onOneServer方法)

Laravel多服务器并发执行migrate冲突的解决方案

Laravel官方暂未为php artisan migrate命令提供类似--on-one-server的开箱即用参数,但可以通过以下两种成熟方案解决问题,核心逻辑和Scheduler的->onOneServer()机制一致,都是基于跨节点共享的排他锁保证单次仅一个节点执行迁移。

方案1:基于Laravel内置原子锁封装自定义命令

该方案和官方->onOneServer()用的是同一套底层原子锁实现,可靠性有保障:

  • 前置要求:项目已配置所有服务器共享的缓存驱动(如Redis、Memcached,不可用本地file缓存)
  • 新建自定义Artisan命令app/Console/Commands/MigrateSingleServer.php,代码如下:
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;

class MigrateSingleServer extends Command
{
    protected $signature = 'migrate:single-server {--force}';
    protected $description = 'Execute migrations only on one server to avoid concurrent conflicts';

    public function handle()
    {
        // 锁有效期设置为10分钟,可根据实际迁移执行时长调整
        $migrationLock = Cache::lock('migration_execution_unique_lock', 600);

        if (!$migrationLock->get()) {
            $this->info('Migration is already running on another server, skip current execution.');
            return 0;
        }

        try {
            // 调用原生migrate命令传递参数
            $this->call('migrate', [
                '--force' => $this->option('force')
            ]);
        } finally {
            // 执行完成主动释放锁
            $migrationLock->release();
        }

        return 0;
    }
}
  • 将部署脚本after_deployment.sh中原有的php artisan migrate --force替换为php artisan migrate:single-server --force即可。抢不到锁的节点会直接跳过迁移执行,不会报错。

方案2:调整CI/CD部署流程拆分执行步骤

如果不想修改项目代码,可以直接调整部署流水线的执行顺序:

  • 先单独触发一台指定的专用部署节点执行php artisan migrate --force,等待迁移执行成功返回后,再批量重启所有业务服务器的Docker容器
  • 该方案不需要改动应用代码,适合不想侵入业务项目的场景。

补充注意:对于支持事务的数据库引擎,Laravel迁移默认会用事务包裹,就算出现并发执行的情况也不会损坏数据库结构,仅会抛出执行错误,加锁/调整流程主要是为了避免部署流程报错中断。

内容的提问来源于stack exchange,提问作者Boring person

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 15:54:04