Ruby on rails 亚马逊弹性豆茎中的Crontab

Ruby on rails 亚马逊弹性豆茎中的Crontab,ruby-on-rails,amazon-web-services,cron,amazon-elastic-beanstalk,rake-task,Ruby On Rails,Amazon Web Services,Cron,Amazon Elastic Beanstalk,Rake Task,我正在用RubyonRails3在AWS-ElasticBeanstalk中做一个cron选项卡,但我不知道出了什么问题 我的.ebextensions/default.config中有此代码 container_commands: 01remove_old_cron_jobs: command: "crontab -r || exit 0" 02send_test_email: command: crontab */2 * * * * rake send_email:t

我正在用RubyonRails3在AWS-ElasticBeanstalk中做一个cron选项卡,但我不知道出了什么问题

我的.ebextensions/default.config中有此代码

container_commands:
  01remove_old_cron_jobs:
    command: "crontab -r || exit 0"
  02send_test_email:
    command: crontab */2 * * * * rake send_email:test
    leader_only: true
02_crontab:
  command: "cat .ebextensions/crontab.txt | crontab"
  leader_only: true
02_crontab:
  command: "/bin/bash .ebextensions/crontab.sh"
  leader_only: true
files:
  "/etc/cron.d/mycron":
    mode: "000644"
    owner: root
    group: root
    content: |
      56 11 * * * root . /opt/elasticbeanstalk/support/envvars && cd /var/app/current && /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test >> /var/app/current/log/cron.log 2>&1

commands:
  remove_old_cron:
    command: "rm -f /etc/cron.d/*.bak"
我收到这个错误:

Failed on instance with return code: 1 Output: Error occurred during build: Command 02send_test_email failed .
更新1

我下一步尝试:

crontab.txt

*/2 * * * * rake send_email:test > /dev/null 2>&1
default.config

container_commands:
  01remove_old_cron_jobs:
    command: "crontab -r || exit 0"
  02send_test_email:
    command: crontab */2 * * * * rake send_email:test
    leader_only: true
02_crontab:
  command: "cat .ebextensions/crontab.txt | crontab"
  leader_only: true
02_crontab:
  command: "/bin/bash .ebextensions/crontab.sh"
  leader_only: true
files:
  "/etc/cron.d/mycron":
    mode: "000644"
    owner: root
    group: root
    content: |
      56 11 * * * root . /opt/elasticbeanstalk/support/envvars && cd /var/app/current && /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test >> /var/app/current/log/cron.log 2>&1

commands:
  remove_old_cron:
    command: "rm -f /etc/cron.d/*.bak"
结果:没有错误,但不起作用

更新2

crontab.sh

crontab -l > /tmp/cronjob
#CRONJOB RULES
echo "*/2 * * * * /usr/bin/wget http://localhost/crontabs/send_test_email > /dev/null 2>&1" >> /tmp/cronjob
#echo "*/2 * * * * rake send_email:test > /dev/null 2>&1" >> /tmp/cronjob

crontab /tmp/cronjob
rm /tmp/cronjob
echo 'Script successful executed, crontab updated.'
default.config

container_commands:
  01remove_old_cron_jobs:
    command: "crontab -r || exit 0"
  02send_test_email:
    command: crontab */2 * * * * rake send_email:test
    leader_only: true
02_crontab:
  command: "cat .ebextensions/crontab.txt | crontab"
  leader_only: true
02_crontab:
  command: "/bin/bash .ebextensions/crontab.sh"
  leader_only: true
files:
  "/etc/cron.d/mycron":
    mode: "000644"
    owner: root
    group: root
    content: |
      56 11 * * * root . /opt/elasticbeanstalk/support/envvars && cd /var/app/current && /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test >> /var/app/current/log/cron.log 2>&1

commands:
  remove_old_cron:
    command: "rm -f /etc/cron.d/*.bak"

结果:可用于url,但不可用于rake任务。

我在.ebextensions中看到这些用于单独的文件,例如:

  02send_test_email:
    command: "cat .ebextensions/crontab | crontab"
    leader_only: true
我还没来得及解决这个问题,但我注意到了这一点。让我们知道这是否有效

更新1/2后:

Cron不知道rake在哪里。您的应用程序从
/var/app/current
运行,您需要从该目录运行
bundle exec rake


Elastic beanstalk在日志记录错误方面非常糟糕,为了正确地记录错误,请对机器执行
ssh
,并进行实验,直到命令正确为止,然后将其放回cron脚本中。您甚至可以尝试重新运行日志中的一些eb脚本,然后将其反转到您的
ebextensions
文件中。

我也遇到了同样的问题。虽然我发现rake任务不能在eb上正确运行的原因是RACK_ENV、RAILS_ENV和BUNDLE_没有
eb违约:

RACK_ENV: production
RAILS_ENV: production
BUNDLE_WITHOUT: test:development
当cron运行rake任务时,它在开发模式下运行,并给出gem not found错误,因为在开发中分组的gem没有安装

您可以通过将cron从以下位置稍微更改一点
来看到这一点:

*/2 * * * * rake send_email:test > /dev/null 2>&1
致:

然后检查/tmp/cron_日志文件
要知道捆绑和耙的位置,请运行

which bundle
which rake
我尝试在cron中的命令中设置RAILS_ENV,但效果不佳
一个快速解决方法是设置

BUNDLE_WITHOUT to null
编辑:

最后我成功了

.ebextensions/.config

files:
  "/tmp/cron_jobs" :
    mode: "000777"
    content: |
      1 10 * * * cd /var/app/current/ && RACK_ENV=production rake some:task >> /var/app/current/log/cron_log 2>&1
    encoding: plain
container_commands:
  01_delete_cron_jobs:
    command: "crontab -r -u webapp || exit 0"
  02_add_cron_jobs:
    command: "crontab /tmp/cron_jobs -u webapp"
    leader_only: true
option_settings:
  - option_name: RAILS_ENV
    value: production
  - option_name: RACK_ENV
    value: production
请注意,删除和添加cron时会出现'-u webapp',这将在用户webapp下运行此cron。上述操作也将在生产模式下运行。输出将转储到log/cron_日志文件中

如果上述方法不起作用,那么在“rake some:task”之前添加“Bundle exec”可能会起作用。

2018年更新 为了在最新版本的Elastic Beanstalk上实现这一点,我将以下内容添加到我的
.ebextensions

.ebextensions/0005\u cron.config

container_commands:
  01remove_old_cron_jobs:
    command: "crontab -r || exit 0"
  02send_test_email:
    command: crontab */2 * * * * rake send_email:test
    leader_only: true
02_crontab:
  command: "cat .ebextensions/crontab.txt | crontab"
  leader_only: true
02_crontab:
  command: "/bin/bash .ebextensions/crontab.sh"
  leader_only: true
files:
  "/etc/cron.d/mycron":
    mode: "000644"
    owner: root
    group: root
    content: |
      56 11 * * * root . /opt/elasticbeanstalk/support/envvars && cd /var/app/current && /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test >> /var/app/current/log/cron.log 2>&1

commands:
  remove_old_cron:
    command: "rm -f /etc/cron.d/*.bak"
我是如何到达那里的: 在AWS EB中尝试cron rake任务时,需要面对四个主要问题:

  • 第一个障碍是确保所有EB和Rails环境变量都已加载。在这个问题上,我用头撞了一下墙,但后来我发现(可能需要登录)。正在运行
    /opt/elasticbeanstalk/support/envvars
    加载所有环境变量

  • 然后,我们需要确保使用
    cd/var/app/current
    cd
    放入当前应用程序目录

  • 接下来,我们需要知道在哪里可以找到
    rake
    可执行文件。它们不安装在普通的
    bin
    目录中,而是位于特定于ruby版本的目录中。要查找可执行文件的位置,请将ssh连接到您的EB服务器(
    EB ssh
    ),然后键入以下内容:

    $ cd /var/app/current
    $ which bundle
    /opt/rubies/ruby-2.3.4/bin/bundle
    $ which rake
    /opt/rubies/ruby-2.3.4/bin/rake
    
    您可能会根据您的ruby版本猜测目录,但是上面的命令会让您确定。基于以上内容,您可以将rake命令构建为:

    /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test
    
    注意:如果更新ruby版本,则可能还需要更新cron配置。这有点脆。我建议你在自述中记下这一点。相信我,六个月后,你会忘记的

  • 第四件事要考虑的是测井。我建议您将日志记录到与其他rails日志相同的位置。我们通过将
    >/var/app/current/log/cron.log 2>&1添加到命令字符串的末尾来实现这一点

    将所有这些放在一起会产生一个
    cron
    命令字符串:

    . /opt/elasticbeanstalk/support/envvars && cd /var/app/current && /opt/rubies/ruby-2.3.4/bin/bundle exec /opt/rubies/ruby-2.3.4/bin/rake send_email:test >> /var/app/current/log/cron.log 2>&1
    

    最后,我引用了最新版本,为我的
    cron
    命令构建了一个
    .ebextensions
    配置文件。结果是
    .ebextensions/0005\u cron.config
    文件显示在这个答案的顶部。

    对我来说没用。我有一个crontab.txt,带有
    */2****rake send\u email:test>/dev/null 2>&1
    ,什么都没有。没有错误,但没有工作。请参阅更新1和更新2。从
    /var/app/current
    运行
    bundle exec
    的任何示例?由于您正在加载环境变量,我认为您应该能够使用
    $RUBY_ROOT
    代替实际路径(例如
    /opt/rubies/RUBY-2.3.4
    ),以避免“为什么这个任务没有运行?“当Ruby版本不可避免地更新时。@Matt,好主意。我还没有时间测试它,但如果您有信心,请随意编辑此答案。
    /opt/rubies/ruby current
    链接到最近Beanstalk ruby机器上的当前ruby版本,因此您可以使用它而不是特定ruby版本的路径。更详细的命令字符串,但没有硬连线路径:
    $(/opt/elasticbeanstalk/bin/get config container-k support_dir)/envvars&&cd$(/opt/elasticbeanstalk/bin/get config container-k app_deploy_dir)&&&&$(/opt/elasticbeanstalk/bin/get-config-container-k script_dir)/use-app-ruby.sh&&bundle-exec-rake-T
    如果它对任何人都有帮助,我的Node.js亚马逊Linux 2环境没有
    envvars
    文件
    get-config
    是另一种选择,但它还没有出现在Amazon Linux 2上(截至2020年6月)。以下是帮助我的解决方法: