95

我想知道是否有办法设置一个 cronjob/task 每分钟执行一次。目前,我的任何实例都应该能够运行此任务。

这是我在配置文件中尝试做的但没有成功:

container_commands:
  01cronjobs:
    command: echo "*/1 * * * * root php /etc/httpd/myscript.php"

我不确定这是否是正确的方法

有任何想法吗?

4

18 回答 18

105

这就是我向 Elastic Beanstalk 添加 cron 作业的方式:

在应用程序的根目录下创建一个名为 .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

这是 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

因此,这个 cron 作业将以 root 用户身份在每天每一小时的每一分钟运行,并将输出丢弃到 /dev/null。/usr/bin/php 是 php 的路径。然后将 some-php-script-here 替换为您的 php 文件的路径。这显然是假设您的 cron 作业需要运行 PHP 文件。

此外,请确保 some_cron_job.txt 文件在文件末尾有一个换行符,就像评论说的那样。否则 cron 将无法运行。

更新: 当 Elastic Beanstalk 扩展您的实例时,此解决方案存在问题。例如,假设您有一个正在运行 cron 作业的实例。您的流量会增加,因此 Elastic Beanstalk 最多可将您扩展到两个实例。leader_only 将确保您在两个实例之间只运行一个 cron 作业。您的流量会减少,而 Elastic Beanstalk 会将您缩减为一个实例。但是,Elastic Beanstalk 不会终止第二个实例,而是终止作为领导者的第一个实例。您现在没有运行任何 cron 作业,因为它们只在第一个终止的实例上运行。 请参阅下面的评论。

更新 2: 请从以下评论中明确说明:AWS 现在具有防止自动实例终止的保护。只需在您的领导者实例上启用它,您就可以开始了。– Nicolás Arévalo 2016 年 10 月 28 日在 9:23

于 2013-03-05T20:50:17.063 回答
59

这是现在(2015+)的官方方式。请先尝试一下,这是目前最简单且最可靠的方法。

根据当前的文档,可以在他们所谓的工作层上运行定期任务

引用文档:

AWS Elastic Beanstalk 支持在运行预定义配置的环境中对工作线程环境层执行定期任务,该配置的解决方案堆栈在容器名称中包含“v1.2.0”。您必须创建一个新环境。

同样有趣的是关于cron.yaml的部分:

要调用定期任务,您的应用程序源包必须在根级别包含一个 cron.yaml 文件。该文件必须包含有关您要安排的定期任务的信息。使用标准 crontab 语法指定此信息。

更新:我们能够完成这项工作。以下是我们经验中的一些重要问题(Node.js 平台):

  • 使用cron.yaml文件时,请确保您拥有最新的 awsebcli,因为旧版本将无法正常工作。
  • 创造新环境也很重要(至少在我们的例子中是这样),而不仅仅是克隆旧环境。
  • 如果您想确保您的 EC2 Worker Tier 实例支持 CRON,请通过 ssh 进入它 ( eb ssh),然后运行cat /var/log/aws-sqsd/default.log​​. 它应该报告为aws-sqsd 2.0 (2015-02-18). 如果您没有 2.0 版本,则在创建环境时出现问题,您需要按上述方式创建新环境。
于 2015-02-25T12:48:29.463 回答
32

关于 jamieb 的响应,正如 alrdinleal 所提到的,您可以使用“leader_only”属性来确保只有一个 EC2 实例运行 cron 作业。

引自http://docs.amazonwebservices.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html

你可以使用leader_only。一个实例被选为 Auto Scaling 组中的领导者。如果 leader_only 值设置为 true,则该命令仅在标记为领导者的实例上运行。

我试图在我的 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

本质上,我使用 cronjobs 创建了一个临时文件,然后将 crontab 设置为从临时文件中读取,然后删除临时文件。希望这可以帮助。

于 2013-01-01T13:44:04.373 回答
12

如上所述,建立任何 crontab 配置的根本缺陷是它只发生在部署时。随着集群自动扩展,然后又缩减,最好也成为第一个关闭的服务器。此外,不会有故障转移,这对我来说至关重要。

我做了一些研究,然后与我们的 AWS 客户专家交谈,以提出想法并验证我提出的解决方案。您可以使用OpsWorks完成此操作,尽管这有点像用房子杀死苍蝇。也可以将Data Pipeline 与 Task Runner一起使用,但这限制了它可以执行的脚本的能力,并且我需要能够运行 PHP 脚本,并且可以访问整个代码库。您还可以在 ElasticBeanstalk 集群之外专门使用一个 EC2 实例,但随后您将无法再进行故障转移。

所以这就是我想出的,这显然是非常规的(正如 AWS 代表评论的那样),可能被认为是一种 hack,但它可以工作并且在故障转移方面很可靠。我选择了使用 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");
}

因此,逐步了解它以及它是如何运行的......您可以像通常在每个 EC2 实例上一样从 crontab 调用脚本。每个脚本在开头都包含这个(或者在我使用它时,每个脚本都包含一个文件),它建立一个 ElasticBeanstalk 对象并检索所有实例的列表。它只使用列表中的第一个服务器,并检查它是否与自己匹配,如果匹配,它会继续,否则它会死掉并关闭。我检查过,返回的列表似乎是一致的,从技术上讲,它只需要保持一分钟左右的一致,因为每个实例都执行预定的 cron。如果它确实发生了变化,那也没关系,因为它再次只与那个小窗口相关。

这绝不是优雅的,但适合我们的特定需求 - 这不是增加额外服务的成本或必须拥有专用的 EC2 实例,并且在发生任何故障时将进行故障转移。我们的 cron 脚本运行维护脚本,这些脚本被放置到 SQS 中,并且集群中的每个服务器都帮助执行。如果它符合您的需要,至少这可能会给您一个替代选择。

-戴维

于 2014-07-17T18:08:25.770 回答
12

我与 AWS 支持代理进行了交谈,这就是我们如何让它为我工作的方式。2015年解决方案:

使用 your_file_name.config 在 .ebextensions 目录中创建一个文件。在配置文件中输入:

文件:
  “/etc/cron.d/cron_example”:
    模式:“000644”
    所有者:根
    组:根
    内容:|
      * * * * * 根 /usr/local/bin/cron_example.sh

  “/usr/local/bin/cron_example.sh”:
    模式:“000755”
    所有者:根
    组:根
    内容:|
      #!/bin/bash

      /usr/local/bin/test_cron.sh || 出口
      echo "Cron 在 "`date` >> /tmp/cron_example.log 运行
      # 现在执行只能在 1 个实例上运行的任务 ...

  “/usr/local/bin/test_cron.sh”:
    模式:“000755”
    所有者:根
    组:根
    内容:|
      #!/bin/bash

      METADATA=/opt/aws/bin/ec2-元数据
      INSTANCE_ID=`$METADATA -i | awk '{打印 $2}'`
      地区=`$元数据-z | awk '{print substr($2, 0, length($2)-1)}'`

      # 找到我们的 Auto Scaling 组名称。
      ASG=`aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" \
        --region $REGION --输出文本 | awk '/aws:autoscaling:groupName/ {print $5}'`

      # 查找组中的第一个实例
      FIRST=`aws 自动缩放 describe-auto-scaling-groups --auto-scaling-group-names $ASG \
        --region $REGION --输出文本 | awk '/InService$/ {打印 $4}' | 排序 | 头-1`

      # 测试它们是否相同。
      [“$FIRST”=“$INSTANCE_ID”]

命令:
  rm_old_cron:
    命令:“rm *.bak”
    cwd:“/etc/cron.d”
    忽略错误:真

该解决方案有两个缺点:

  1. 在后续部署中,Beanstalk 将现有的 cron 脚本重命名为 .bak,但 cron 仍将运行它。您的 Cron 现在在同一台机器上执行两次。
  2. 如果您的环境扩展,您将获得多个实例,所有实例都运行您的 cron 脚本。这意味着您的邮件截图被重复,或者您的数据库档案被重复

解决方法:

  1. 确保任何创建 cron 的 .ebextensions 脚本也会在后续部署中删除 .bak 文件。
  2. 有一个帮助脚本,它执行以下操作: -- 从元数据获取当前实例 ID -- 从 EC2 标签获取当前 Auto Scaling 组名称 -- 获取该组中的 EC2 实例列表,按字母顺序排序。-- 从该列表中获取第一个实例。-- 将第 1 步中的实例 ID 与第 4 步中的第一个实例 ID 进行比较。然后您的 cron 脚本可以使用此帮助程序脚本来确定它们是否应该执行。

警告:

  • 用于 Beanstalk 实例的 IAM 角色需要 ec2:DescribeTags 和 autoscaling:DescribeAutoScalingGroups 权限
  • 从中选择的实例是 Auto Scaling 显示为 InService 的实例。这并不一定意味着它们已完全启动并准备好运行您的 cron。

如果您使用默认 beanstalk 角色,则无需设置 IAM 角色。

于 2015-09-26T08:23:49.993 回答
7

如果您使用的是 Rails,则可以使用ever-elasticbeanstalk gem。它允许您在所有实例或仅一个实例上运行 cron 作业。它每分钟检查一次以确保只有一个“leader”实例,如果没有,它将自动将一台服务器提升为“leader”。这是必需的,因为 Elastic Beanstalk 在部署期间仅具有领导者的概念,并且可能在扩展时随时关闭任何实例。

更新 我改用 AWS OpsWorks 并且不再维护这个 gem。如果您需要的功能超出了 Elastic Beanstalk 基础知识中的可用功能,我强烈建议您切换到 OpsWorks。

于 2013-06-24T21:58:40.477 回答
6

您真的不想在 Elastic Beanstalk 上运行 cron 作业。由于您将拥有多个应用程序实例,这可能会导致竞争条件和其他奇怪的问题。实际上,我最近在博客上写过这个(页面下方的第 4 或第 5 个提示)。简短版本:根据应用程序,使用 SQS 之类的作业队列或iron.io 之类的第三方解决方案。

于 2012-12-31T19:06:34.940 回答
6

2017:如果你使用 Laravel5+

你只需要 2 分钟来配置它:

  • 创建工人层
  • 安装 laravel-aws-worker

    composer require dusterio/laravel-aws-worker

  • 将 cron.yaml 添加到根文件夹:

将 cron.yaml 添加到应用程序的根文件夹(这可以是您的存储库的一部分,或者您可以在部署到 EB 之前添加此文件 - 重要的是此文件在部署时存在):

version: 1
cron:
 - name: "schedule"
   url: "/worker/schedule"
   schedule: "* * * * *"

而已!

App\Console\Kernel现在将执行您的所有任务

详细说明和解释:https ://github.com/dusterio/laravel-aws-worker

如何在 Laravel 中编写任务:https ://laravel.com/docs/5.4/scheduling

于 2017-02-24T11:25:35.390 回答
3

使用files代替的更易读的解决方案container_commands

文件:
  “/etc/cron.d/my_cron”:
    模式:“000644”
    所有者:根
    组:根
    内容:|
      # 覆盖默认电子邮件地址
      MAILTO="example@gmail.com"
      # 每五分钟运行一次 Symfony 命令(作为 ec2-user)
      */10 * * * * ec2-user /usr/bin/php /var/app/current/app/console do:something
    编码:普通
命令:
  # 删除 Elastic Beanstalk 创建的备份文件
  clear_cron_backup:
    命令:rm -f /etc/cron.d/watson.bak

请注意,该格式与通常的 crontab 格式不同,因为它指定了运行命令的用户。

于 2014-03-27T13:11:03.657 回答
3

我2018年的1分钱

这是正确的方法(使用django/pythondjango_crontab应用程序):

.ebextensions文件夹内创建一个像这样的文件98_cron.config

files:
  "/tmp/98_create_cron.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/sh
      cd /
      sudo /opt/python/run/venv/bin/python /opt/python/current/app/manage.py crontab remove > /home/ec2-user/remove11.txt
      sudo /opt/python/run/venv/bin/python /opt/python/current/app/manage.py crontab add > /home/ec2-user/add11.txt 

container_commands:
    98crontab:
        command: "mv /tmp/98_create_cron.sh /opt/elasticbeanstalk/hooks/appdeploy/post && chmod 774 /opt/elasticbeanstalk/hooks/appdeploy/post/98_create_cron.sh"
        leader_only: true

它需要container_commands代替commands

于 2018-03-16T16:40:56.473 回答
2

当新的领导者出现时,有人想知道leader_only 的自动缩放问题。我似乎不知道如何回复他们的评论,但请参阅此链接:http ://blog.paulopoiati.com/2013/08/25/running-cron-in-elastic-beanstalk-auto-scaling-环境/

于 2013-10-20T05:05:14.663 回答
2

来自亚马逊的最新示例是最简单和最有效的(周期性任务):

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features-managing-env-tiers.html

您可以在其中创建一个单独的工作层来执行您的任何 cron 作业。创建 cron.yaml 文件并将其放在您的根文件夹中。我遇到的一个问题(在 cron 似乎没有执行之后)是发现我的 CodePipeline 无权执行 dynamodb 修改。基于此,在 IAM -> 角色 -> yourpipeline 下添加 FullDynamoDB 访问并重新部署(弹性 beantalk)后,它运行良好。

于 2019-12-29T14:02:17.463 回答
2

所以我们已经为此苦苦挣扎了一段时间,在与 AWS 代表讨论后,我终于想出了我认为最好的解决方案。

使用带有 cron.yaml 的工作层绝对是最简单的解决方法。但是,文档没有明确说明的是,这会将作业置于您用于实际运行作业的 SQS 队列的末尾。如果您的 cron 作业对时间敏感(很多都是),这是不可接受的,因为它取决于队列的大小。一种选择是使用完全独立的环境来运行 cron 作业,但我认为这太过分了。

其他一些选项(例如检查您是否是列表中的第一个实例)也不理想。如果当前的第一个实例正在关闭过程中怎么办?

实例保护也可能带来问题 - 如果该实例被锁定/冻结怎么办?

重要的是要了解 AWS 本身如何管理 cron.yaml 功能。有一个 SQS 守护进程使用 Dynamo 表来处理“领导选举”。它频繁地写入这张表,如果当前的leader短时间内没有写入,下一个实例将接替成为leader。这是守护进程决定哪个实例将作业触发到 SQS 队列的方式。

我们可以重新利用现有功能,而不是尝试重写我们自己的功能。你可以在这里看到完整的解决方案:https ://gist.github.com/dorner/4517fe2b8c79ccb3971084ec28267f27

那是在 Ruby 中,但您可以轻松地将其调整为具有 AWS 开发工具包的任何其他语言。本质上,它检查当前领导者,然后检查状态以确保其处于良好状态。它将循环直到有一个处于良好状态的当前领导者,如果当前实例是领导者,则执行作业。

于 2017-05-26T14:45:04.623 回答
1

以下是解决方案的完整说明:

http://blog.paulopoiati.com/2013/08/25/running-cron-in-elastic-beanstalk-auto-scaling-environment/

于 2013-08-25T23:49:28.330 回答
0

根据user1599237的回答原则,您让 cron 作业在所有实例上运行,但是在作业开始时确定是否应该允许它们运行,我提出了另一个解决方案。

我没有查看正在运行的实例(并且必须存储您的 AWS 密钥和秘密),而是使用我已经从所有实例连接到的 MySQL 数据库。

它没有缺点,只有优点:

  • 没有额外的实例或费用
  • 坚如磐石的解决方案 - 没有双重执行的机会
  • 可扩展 - 随着您的实例扩展和缩减自动工作
  • 故障转移 - 在实例发生故障时自动工作

或者,您也可以使用通常共享的文件系统(例如通过 NFS 协议的AWS EFS )而不是数据库。

以下解决方案是在 PHP 框架Yii中创建的,但您可以轻松地将其调整为其他框架和语言。异常处理程序Yii::$app->system也是我自己的一个模块。用你正在使用的任何东西替换它。

/**
 * Obtain an exclusive lock to ensure only one instance or worker executes a job
 *
 * Examples:
 *
 * `php /var/app/current/yii process/lock 60 empty-trash php /var/app/current/yii maintenance/empty-trash`
 * `php /var/app/current/yii process/lock 60 empty-trash php /var/app/current/yii maintenance/empty-trash StdOUT./test.log`
 * `php /var/app/current/yii process/lock 60 "empty trash" php /var/app/current/yii maintenance/empty-trash StdOUT./test.log StdERR.ditto`
 * `php /var/app/current/yii process/lock 60 "empty trash" php /var/app/current/yii maintenance/empty-trash StdOUT./output.log StdERR./error.log`
 *
 * Arguments are understood as follows:
 * - First: Duration of the lock in minutes
 * - Second: Job name (surround with quotes if it contains spaces)
 * - The rest: Command to execute. Instead of writing `>` and `2>` for redirecting output you need to write `StdOUT` and `StdERR` respectively. To redirect stderr to stdout write `StdERR.ditto`.
 *
 * Command will be executed in the background. If determined that it should not be executed the script will terminate silently.
 */
public function actionLock() {
    $argsAll = $args = func_get_args();
    if (!is_numeric($args[0])) {
        \Yii::$app->system->error('Duration for obtaining process lock is not numeric.', ['Args' => $argsAll]);
    }
    if (!$args[1]) {
        \Yii::$app->system->error('Job name for obtaining process lock is missing.', ['Args' => $argsAll]);
    }

    $durationMins = $args[0];
    $jobName = $args[1];
    $instanceID = null;
    unset($args[0], $args[1]);

    $command = trim(implode(' ', $args));
    if (!$command) {
        \Yii::$app->system->error('Command to execute after obtaining process lock is missing.', ['Args' => $argsAll]);
    }

    // If using AWS Elastic Beanstalk retrieve the instance ID
    if (file_exists('/etc/elasticbeanstalk/.aws-eb-system-initialized')) {
        if ($awsEb = file_get_contents('/etc/elasticbeanstalk/.aws-eb-system-initialized')) {
            $awsEb = json_decode($awsEb);
            if (is_object($awsEb) && $awsEb->instance_id) {
                $instanceID = $awsEb->instance_id;
            }
        }
    }

    // Obtain lock
    $updateColumns = false;  //do nothing if record already exists
    $affectedRows = \Yii::$app->db->createCommand()->upsert('system_job_locks', [
        'job_name' => $jobName,
        'locked' => gmdate('Y-m-d H:i:s'),
        'duration' => $durationMins,
        'source' => $instanceID,
    ], $updateColumns)->execute();
    // The SQL generated: INSERT INTO system_job_locks (job_name, locked, duration, source) VALUES ('some-name', '2019-04-22 17:24:39', 60, 'i-HmkDAZ9S5G5G') ON DUPLICATE KEY UPDATE job_name = job_name

    if ($affectedRows == 0) {
        // record already exists, check if lock has expired
        $affectedRows = \Yii::$app->db->createCommand()->update('system_job_locks', [
                'locked' => gmdate('Y-m-d H:i:s'),
                'duration' => $durationMins,
                'source' => $instanceID,
            ],
            'job_name = :jobName AND DATE_ADD(locked, INTERVAL duration MINUTE) < NOW()', ['jobName' => $jobName]
        )->execute();
        // The SQL generated: UPDATE system_job_locks SET locked = '2019-04-22 17:24:39', duration = 60, source = 'i-HmkDAZ9S5G5G' WHERE job_name = 'clean-trash' AND DATE_ADD(locked, INTERVAL duration MINUTE) < NOW()

        if ($affectedRows == 0) {
            // We could not obtain a lock (since another process already has it) so do not execute the command
            exit;
        }
    }

    // Handle redirection of stdout and stderr
    $command = str_replace('StdOUT', '>', $command);
    $command = str_replace('StdERR.ditto', '2>&1', $command);
    $command = str_replace('StdERR', '2>', $command);

    // Execute the command as a background process so we can exit the current process
    $command .= ' &';

    $output = []; $exitcode = null;
    exec($command, $output, $exitcode);
    exit($exitcode);
}

这是我正在使用的数据库架构:

CREATE TABLE `system_job_locks` (
    `job_name` VARCHAR(50) NOT NULL,
    `locked` DATETIME NOT NULL COMMENT 'UTC',
    `duration` SMALLINT(5) UNSIGNED NOT NULL COMMENT 'Minutes',
    `source` VARCHAR(255) NULL DEFAULT NULL,
    PRIMARY KEY (`job_name`)
)
于 2019-04-22T17:32:26.830 回答
0

如果您想在 PHP 中执行此操作,这是一个修复程序。您只需要 .ebextensions 文件夹中的 cronjob.config 就可以让它像这样工作。

files:
  "/etc/cron.d/my_cron":
    mode: "000644"
    owner: root
    group: root
    content: |
        empty stuff
    encoding: plain
commands:
  01_clear_cron_backup:
    command: "rm -f /etc/cron.d/*.bak"
  02_remove_content:
    command: "sudo sed -i 's/empty stuff//g' /etc/cron.d/my_cron"
container_commands:
  adding_cron:
    command: "echo '* * * * * ec2-user . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/app/current/index.php cron sendemail > /tmp/sendemail.log 2>&1' > /etc/cron.d/my_cron"
    leader_only: true

envvars 获取文件的环境变量。您可以如上所述在 tmp/sendemail.log 上调试输出。

希望这对某人有所帮助,因为它肯定对我们有所帮助!

于 2017-05-15T03:12:10.830 回答
0

要控制 Auto Scaling 是否可以在缩减时终止特定实例,请使用实例保护。您可以在 Auto Scaling 组或单个 Auto Scaling 实例上启用实例保护设置。当 Auto Scaling 启动实例时,该实例会继承 Auto Scaling 组的实例保护设置。您可以随时更改 Auto Scaling 组或 Auto Scaling 实例的实例保护设置。

http://docs.aws.amazon.com/autoscaling/latest/userguide/as-instance-termination.html#instance-protection

于 2016-08-10T20:23:08.907 回答
0

如果需要通过 cron 运行 php 文件并且设置了任何 NAT 实例,那么我有另一个解决方案,那么您可以将 cronjob 放在 NAT 实例上并通过 wget 运行 php 文件。

于 2016-08-22T09:25:11.710 回答