代码之家  ›  专栏  ›  技术社区  ›  Niklas

如何在AWS弹性Beanstalk上设置和使用Laravel调度?

  •  5
  • Niklas  · 技术社区  · 6 年前

    脚本

    作为Laravel和ElasticBeanstalk的新用户,我很快发现自己需要像我们大多数人一样安排操作。

    在过去,我一直使用简单的crontab调度。所以现在我站在一个问题列表前:

    • 如何使用crontab运行laravel代码?
    • 如何在我的弹性Beanstalk环境中设置crontab?

    找到这些问题的答案并不难。然而,将它们结合起来并让它们全部工作,结果却有点棘手,这就是为什么我决定在这里为其他努力使其正常工作的人分享解决方案的原因。


    环境

    • 拉拉维尔5.6
    • 7.1菲律宾比索
    1 回复  |  直到 6 年前
        1
  •  7
  •   Niklas    6 年前

    TL;医生:

    见工作 .ebextentions 应答结束时的配置。


    环境

    • 拉拉维尔5.6
    • 7.1菲律宾比索

    如何使用crontab运行laravel代码?

    这个问题的答案当然是最明显的,如果你对拉拉维尔的了解最浅,你肯定知道答案: Scheduling 你看!

    我不会让你厌烦解释Laravel日程安排的精彩之处,因为你可以自己在文档中阅读它。

    但我们需要采取的关键是,Laravel调度使用crontab来执行,如文档中所述:

    * * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
    

    这给我们带来了下一个更棘手的问题…


    如何在我的弹性Beanstalk环境中设置crontab?

    乍一看,这个问题的答案似乎相当直截了当。我在AWS Knownledge中心找到了这个: How do I create a cron job on EC2 instances in an Elastic Beanstalk environment?

    在这里,他们描述了如何使用.ebextensions在弹性Beanstalk EC2机器上设置cron作业。简而言之,它所做的就是在目录中创建一个新文件 /etc/cron.d/ 我们把我们想要的亲信工作放在里面。

    然后,crontab将此目录中的文件作为 root 用户。正如我在下面所评论的,我走进了一些陷阱:

    files:
    
        # The name of the file should not contain any dot (.) or dash (-), this can
        # cause the script not to run. Underscore (_) is OK.
        "/etc/cron.d/mycron":
    
            # This permissions is important so that root user can run the script.
            mode: "000644"
    
            # As the file is run by the root user it needs to be the owner of the file.
            owner: root
    
            # For consistency it's a good idea to have root as the group aswell.
            group: root
    
            # NOTE: We need to explicitly tell the cron job to be run as the root user!
            content: |
                * * * * * root /usr/local/bin/myscript.sh 
    
    # There need to be a new line after the actual cron job in the file.
    

    一旦我们清除了所有这些陷阱,现在是时候从上面开始执行Laravel调度cron任务了。看起来应该是这样的:

    files:
        "/etc/cron.d/schedule_run":
            mode: "000644"
            owner: root
            group: root
            content: |
                * * * * * root php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
    

    不过,在大多数情况下,这不会真正起作用。 .这是因为Laravel调度程序无法访问您的env变量,而且必须明显地不是您的数据库设置。

    我在这里找到了答案: How to Get Laravel Task Scheduling Working on AWS Elastic Beanstalk Cron

    向乔治·布尼什大喊一声,我向你致敬,先生,我和你分享了这一切!

    因此,通过这最后一块拼图,我终于能够让设置正常工作:


    工作方案

    文件结构:

    [Project root]
        |-- .ebextensions
        |        |-- cronjob.config
    

    cronjob.config:

    files:
        "/etc/cron.d/schedule_run":
            mode: "000644"
            owner: root
            group: root
            content: |
                * * * * * root . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/www/html/artisan schedule:run 1>> /dev/null 2>&1
    
    commands:
        remove_old_cron:
            command: "rm -f /etc/cron.d/*.bak"
    

    在AWS弹性Beanstalk上使用Laravel调度时的提示!

    由于弹性Beanstalk的一个关键特性是,它可以在需要时自动缩放和添加更多服务器,因此您可能希望了解Laravel调度中的新特性: Running Tasks On One Server .

    在许多情况下,您不希望在多个服务器上执行cron作业。例如,如果您有发送电子邮件的预定命令,则不希望这些邮件多次发送。

    注: 这要求您使用memcached或redis作为缓存引擎,如文档中所述。如果没有,请看一下AWS服务 Elasticache .

    注2: 使用时 onOneServer() 必须使用 name() 方法(调用前 OnOneServer()。 )。就像这样:

    $schedule->command('my:task')
        ->name('my:task')
        ->daily()
        ->onOneServer();