EC2:Laravel迁移在实例上运行多次

3
我们目前遇到了一个非常奇怪的问题。我们的技术栈涉及 AWS Elastic Beanstalk、EC2 和 Laravel,并使用 Bitbucket Pipelines 部署代码。
问题在于,每当我们在部署中包含一个迁移时,它会被运行两次(在此环境中 EC2 实例的数量一样多)。
我们的脚本位于 ".ebextensions" 目录下:
option_settings:
  "aws:elasticbeanstalk:container:php:phpini":
    document_root: /public
container_commands:
    01initdb:
        command: "php artisan migrate"

由于系统无法检测到此迁移已经运行,我们最终多次破坏了部署。

有人遇到过这个问题吗?

更新 由于在构建脚本中添加php artisan migrate会导致MySQL连接被拒绝,因此我们想出了这种实现方法。


我没有使用过Laravel和AWS,但是php artisan:migrate依赖于一个migrations表来知道哪些迁移已经运行,哪些没有。只要这个表在多个实例之间正确共享,多次运行它不应该导致任何冲突...除非你遇到了竞争条件。 - sheng
@ShengSlogar 没错,有一个名为 migrations 的东西跟踪了后者。 我也是这么想的。实例之间的竞争条件导致了部署中的问题。 - thitami
1个回答

3

有很多方法可以做到这一点:

  1. 让一个操作服务器运行所有需要在单个服务器上运行的任务。您的Bitbucket流水线可以触发此操作服务器以进行单服务器任务,而触发其他服务器以进行多服务器任务。
  2. 创建自定义Artisan命令,获取锁(DB或缓存)以运行迁移,同时避免并行运行/竞争条件。
  3. 按顺序触发部署(不知道Beanstalk是否支持这种方式)。
  4. 正如OP所提到的,将leader_only: true标志设置为Elastic Beanstalk脚本仅在单个实例上运行该命令即可解决问题!

2
感谢@Paras的好建议!我已经在Elastic Beanstalk脚本中应用了leader_only: true标志,这很可能是另一个解决方案。 - thitami
感谢@thitami的分享,我已经更新了我的答案,包括你的解决方案。看起来是最好的一个! :) - Paras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接