One*_*ema 82 cron crontab amazon-web-services amazon-elastic-beanstalk
我想知道是否有办法设置每分钟执行一次cronjob /任务.目前,我的任何实例都应该能够运行此任务.
这是我在配置文件中尝试做的事情没有成功:
container_commands:
01cronjobs:
command: echo "*/1 * * * * root php /etc/httpd/myscript.php"
Run Code Online (Sandbox Code Playgroud)
我不确定这是否是正确的方法
有任何想法吗?
Ana*_*ica 90
在应用程序的根目录下创建一个名为.ebextensions的文件夹(如果它尚不存在).然后在.ebextensions文件夹中创建一个配置文件.我将使用example.config进行说明.然后将其添加到example.config
container_commands:
01_some_cron_job:
command: "cat .ebextensions/some_cron_job.txt > /etc/cron.d/some_cron_job && chmod 644 /etc/cron.d/some_cron_job"
leader_only: true
Run Code Online (Sandbox Code Playgroud)
这是Elastic Beanstalk的YAML配置文件.确保将其复制到文本编辑器中时,文本编辑器使用空格而不是制表符.否则,当您将其推送到EB时,您将收到YAML错误.
这样做的是创建一个名为01_some_cron_job的命令.命令按字母顺序运行,因此01确保它作为第一个命令运行.
然后,该命令获取名为some_cron_job.txt的文件的内容,并将其添加到/etc/cron.d中名为some_cron_job的文件中.
然后,该命令将更改/etc/cron.d/some_cron_job文件的权限.
leader_only键确保命令仅在被视为领导者的ec2实例上运行.而不是在每个ec2实例上运行,而不是运行.
然后在.ebextensions文件夹中创建一个名为some_cron_job.txt的文件.您将把cron作业放在此文件中.
例如:
# The newline at the end of this file is extremely important. Cron won't run without it.
* * * * * root /usr/bin/php some-php-script-here > /dev/null
Run Code Online (Sandbox Code Playgroud)
所以这个cron作业将以root用户的身份每天每小时运行一次,并将输出丢弃到/ dev/null./ usr/bin/php是php的路径.然后用你的php文件的路径替换some-php-script-here.这显然是假设您的cron作业需要运行PHP文件.
另外,请确保some_cron_job.txt文件在文件末尾有一个换行符,就像评论所说的那样.否则cron将无法运行.
更新: 当Elastic Beanstalk扩展您的实例时,此解决方案存在问题.例如,假设您有一个运行cron作业的实例.您的流量会增加,因此Elastic Beanstalk会将您扩展到两个实例.leader_only将确保您只在两个实例之间运行一个cron作业.您的流量减少,Elastic Beanstalk将您缩小到一个实例.但是,Elastic Beanstalk不是终止第二个实例,而是终止作为领导者的第一个实例.您现在没有运行任何cron作业,因为它们仅在已终止的第一个实例上运行. 请参阅以下评论.
更新2: 从下面的评论中明确说明:AWS现在可以防止自动实例终止.只需在你的领导实例上启用它就可以了. - NicolásArévalo2016年10月28日9:23
xar*_*lis 56
根据当前的文档,人们可以在他们所谓的工人层上运行定期任务.
引用文档:
AWS Elastic Beanstalk支持在运行预定义配置的环境中的工作线程环境层的定期任务,其中包含容器名称中包含"v1.2.0"的解决方案堆栈.您必须创建一个新环境.
有趣的是关于cron.yaml的部分:
要调用定期任务,应用程序源包必须在根级别包含cron.yaml文件.该文件必须包含有关要安排的定期任务的信息.使用标准crontab语法指定此信息.
更新:我们能够完成这项工作.以下是我们的经验(Node.js平台)的一些重要问题:
eb ssh),然后运行cat /var/log/aws-sqsd/default.log.它应该报告为aws-sqsd 2.0 (2015-02-18).如果您没有2.0版本,那么在创建环境时出现问题,您需要创建一个如上所述的新环境.bet*_*ife 31
关于jamieb的响应,并且正如alrdinleal所提到的,您可以使用'leader_only'属性来确保只有一个EC2实例运行cron作业.
引自http://docs.amazonwebservices.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html:
你可以使用leader_only.选择一个实例作为Auto Scaling组的领导者.如果leader_only值设置为true,则该命令仅在标记为leader的实例上运行.
我试图在我的eb上实现类似的东西,所以如果我解决它将更新我的帖子.
更新:
好吧,我现在使用以下eb配置工作cronjobs:
files:
"/tmp/cronjob" :
mode: "000777"
owner: ec2-user
group: ec2-user
content: |
# clear expired baskets
*/10 * * * * /usr/bin/wget -o /dev/null http://blah.elasticbeanstalk.com/basket/purge > $HOME/basket_purge.log 2>&1
# clean up files created by above cronjob
30 23 * * * rm $HOME/purge*
encoding: plain
container_commands:
purge_basket:
command: crontab /tmp/cronjob
leader_only: true
commands:
delete_cronjob_file:
command: rm /tmp/cronjob
Run Code Online (Sandbox Code Playgroud)
基本上,我使用cronjobs创建一个临时文件,然后将crontab设置为从临时文件中读取,然后删除临时文件.希望这可以帮助.
小智 12
如上所述,建立任何crontab配置的根本缺陷是它只在部署时发生.随着群集自动放大,然后退回,最好也是第一个关闭的服务器.此外,没有故障转移,对我来说这是至关重要的.
我做了一些研究,然后与我们的AWS账户专家交谈,以反映想法并确认我提出的解决方案.你可以用OpsWorks完成这个任务,虽然它有点像用房子来杀死苍蝇.也可以将数据管道与任务运行器一起使用,但这在它可以执行的脚本中具有有限的能力,并且我需要能够运行PHP脚本,并且可以访问整个代码库.您还可以在ElasticBeanstalk集群之外专用EC2实例,但之后您不会再进行故障转移.
所以这就是我想出来的,这显然是非常规的(正如AWS代表所评论的那样)并且可能被认为是一种黑客行为,但它可以运行并且可以通过故障转移实现.我选择了使用SDK的编码解决方案,我将在PHP中展示,尽管您可以使用您喜欢的任何语言执行相同的方法.
// contains the values for variables used (key, secret, env)
require_once('cron_config.inc');
// Load the AWS PHP SDK to connection to ElasticBeanstalk
use Aws\ElasticBeanstalk\ElasticBeanstalkClient;
$client = ElasticBeanstalkClient::factory(array(
'key' => AWS_KEY,
'secret' => AWS_SECRET,
'profile' => 'your_profile',
'region' => 'us-east-1'
));
$result = $client->describeEnvironmentResources(array(
'EnvironmentName' => AWS_ENV
));
if (php_uname('n') != $result['EnvironmentResources']['Instances'][0]['Id']) {
die("Not the primary EC2 instance\n");
}
Run Code Online (Sandbox Code Playgroud)
因此,逐步介绍它以及它如何运作...您可以像往常一样在每个EC2实例上调用crontab中的脚本.每个脚本在开头都包含它(或者每个脚本包含一个文件,因为我使用它),它建立一个ElasticBeanstalk对象并检索所有实例的列表.它仅使用列表中的第一个服务器,并检查它是否与自身匹配,如果它继续,则会死亡,然后关闭.我已经检查过并且返回的列表似乎是一致的,从技术上讲,它只需要一分钟左右一致,因为每个实例都执行预定的cron.如果确实发生了变化,那就不重要了,因为它只与那个小窗口有关.
这并不优雅,但适合我们的特定需求 - 这不是通过额外服务增加成本或必须有专用EC2实例,并且在发生任何故障时都会进行故障转移.我们的cron脚本运行维护脚本,这些脚本放入SQS,集群中的每个服务器都有助于执行.如果符合您的需求,至少可以为您提供备用选项.
-Davey
我与AWS支持代理进行了交谈,这就是我们为此工作的方式.2015解决方案:
使用your_file_name.config在.ebextensions目录中创建一个文件.在配置文件输入中:
files:
"/etc/cron.d/cron_example":
mode: "000644"
owner: root
group: root
content: |
* * * * * root /usr/local/bin/cron_example.sh
"/usr/local/bin/cron_example.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/bash
/usr/local/bin/test_cron.sh || exit
echo "Cron running at " `date` >> /tmp/cron_example.log
# Now do tasks that should only run on 1 instance ...
"/usr/local/bin/test_cron.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/bash
METADATA=/opt/aws/bin/ec2-metadata
INSTANCE_ID=`$METADATA -i | awk '{print $2}'`
REGION=`$METADATA -z | awk '{print substr($2, 0, length($2)-1)}'`
# Find our Auto Scaling Group name.
ASG=`aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" \
--region $REGION --output text | awk '/aws:autoscaling:groupName/ {print $5}'`
# Find the first instance in the Group
FIRST=`aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ASG \
--region $REGION --output text | awk '/InService$/ {print $4}' | sort | head -1`
# Test if they're the same.
[ "$FIRST" = "$INSTANCE_ID" ]
commands:
rm_old_cron:
command: "rm *.bak"
cwd: "/etc/cron.d"
ignoreErrors: true
该解决方案有两个缺点:
解决方法:
警告:
如果使用默认的beanstalk角色,则不必设置IAM角色.
如果您正在使用Rails,则可以使用never-elasticbeanstalk gem.它允许您在所有实例上运行cron作业或只运行一个.它会检查每一分钟以确保只有一个"领导者"实例,并且如果没有,则会自动将一个服务器提升为"领导者".这是必需的,因为Elastic Beanstalk在部署期间仅具有leader的概念,并且可以在扩展时随时关闭任何实例.
更新 我切换到使用AWS OpsWorks并且不再维护此gem.如果您需要比Elastic Beanstalk基础知识更多的功能,我强烈建议您切换到OpsWorks.
你真的不想在Elastic Beanstalk上运行cron作业.由于您将拥有多个应用程序实例,因此可能会导致竞争条件和其他奇怪问题.我实际上最近在博客上写了这篇文章(页面上的第4或第5个提示).简短版本:根据应用程序,使用SQS等作业队列或iron.io等第三方解决方案.
您只需要 2 分钟即可配置它:
安装 laravel-aws-worker
composer require dusterio/laravel-aws-worker
将 cron.yaml 添加到根文件夹:
将 cron.yaml 添加到您的应用程序的根文件夹(这可以是您的存储库的一部分,或者您可以在部署到 EB 之前添加此文件 - 重要的是该文件在部署时存在):
version: 1
cron:
- name: "schedule"
url: "/worker/schedule"
schedule: "* * * * *"
Run Code Online (Sandbox Code Playgroud)
App\Console\Kernel现在将执行您的所有任务
详细说明和说明:https : //github.com/dusterio/laravel-aws-worker
如何在 Laravel 内部编写任务:https ://laravel.com/docs/5.4/scheduling
| 归档时间: |
|
| 查看次数: |
54929 次 |
| 最近记录: |