web-dev-qa-db-ja.com

cronjobを実行するAWS Elastic Beanstalk

Cronjob/taskを毎分実行するように設定する方法があるかどうか知りたいです。現在、どのインスタンスでもこのタスクを実行できるはずです。

これは私が成功せずに設定ファイルでやろうとしたことです:

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

これが正しい方法であるかどうかはよくわかりません

何か案は?

82
Onema

これは、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ユーザーとして毎日1時間ごとに実行され、/ dev/nullへの出力を破棄します。/usr/bin/phpはphpへのパスです。次に、some-php-script-hereをphpファイルへのパスに置き換えます。これは明らかに、cronジョブでPHPファイルを実行する必要があることを前提としています。

また、コメントが言っているように、some_cron_job.txtファイルの最後に改行があることを確認してください。そうしないと、cronは実行されません。

更新: Elastic Beanstalkがインスタンスをスケールアップすると、このソリューションに問題があります。たとえば、cronジョブが実行されているインスタンスが1つあるとします。トラフィックが増加するため、Elastic Beanstalkは2つのインスタンスにスケールアップします。 leader_onlyは、2つのインスタンス間で実行されるcronジョブが1つだけであることを保証します。トラフィックが減少し、Elastic Beanstalkは1つのインスタンスにスケールダウンします。ただし、Elastic Beanstalkは2番目のインスタンスを終了する代わりに、リーダーであった最初のインスタンスを終了します。終了した最初のインスタンスでのみ実行されていたため、cronジョブは実行されていません。 以下のコメントを参照してください。

更新2:以下のコメントからこれを明確にするだけです。AWSには、インスタンスの自動終了に対する保護があります。リーダーインスタンスで有効にするだけで、準備完了です。 –ニコラスアレバロ16年10月28日9:23に

90
Anarchtica

これが今の公式の方法です(2015+)。最初にこれを試してください。これは現在利用できる最も簡単な方法であり、最も信頼性の高い方法でもあります。

現在のドキュメントによると、1つは定期タスクを実行できるいわゆる ワーカー層 です。

ドキュメントの引用:

AWS Elastic Beanstalkは、コンテナ名に「v1.2.0」を含むソリューションスタックで事前定義された構成を実行している環境のワーカー環境層の定期的なタスクをサポートします。新しい環境を作成する必要があります。

cron.yamlに関する部分も興味深いです。

定期的なタスクを呼び出すには、アプリケーションソースバンドルにルートレベルでcron.yamlファイルを含める必要があります。ファイルには、スケジュールする定期的なタスクに関する情報が含まれている必要があります。標準のcrontab構文を使用してこの情報を指定します。

Update:この作業を取得できました。経験からの重要な落とし穴をいくつか紹介します(Node.jsプラットフォーム):

  • cron.yamlファイルを使用する場合は、最新の awsebcli があることを確認してください。古いバージョンは適切に動作しないためです。
  • また、古い環境を複製するだけでなく、新しい環境を作成することも重要です(少なくとも私たちの場合はそうでした)。
  • EC2ワーカー層インスタンスでCRONがサポートされていることを確認するには、ssh(_eb ssh_)にsshし、_cat /var/log/aws-sqsd/default.log_を実行します。 aws-sqsd 2.0 (2015-02-18)として報告する必要があります。 2.0バージョンがない場合、環境を作成するときに何かがおかしくなり、上記のように新しい環境を作成する必要があります。
56
xaralis

Jamiebの応答に関して、また、一般的な言及として、「leader_only」プロパティを使用して、1つのEC2インスタンスのみがcronジョブを実行できるようにすることができます。

http://docs.amazonwebservices.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html からの引用:

leader_onlyを使用できます。 1つのインスタンスがAuto Scalingグループのリーダーとして選択されます。 leader_only値がtrueに設定されている場合、コマンドはリーダーとしてマークされているインスタンスでのみ実行されます。

私はebで同様のことを達成しようとしているので、解決したら投稿を更新します。

UPDATE:

さて、次のeb configを使用してcronジョブを実行できます。

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

基本的に、cronジョブで一時ファイルを作成し、一時ファイルから読み込むようにcrontabを設定し、その後一時ファイルを削除します。お役に立てれば。

31
beterthanlife

上記のように、crontab構成を確立する際の基本的な欠陥は、展開時にのみ発生することです。クラスターが自動的にスケールアップされてからダウンされると、最初のサーバーがオフになることも好まれます。さらに、フェールオーバーはありませんが、これは私にとって重要でした。

いくつかの調査を行った後、AWSアカウントスペシャリストと意見を交換して、思いついたソリューションを検証しました。これは OpsWorks で実現できますが、ハエを殺すために家を使うようなものです。 Task Runnerを使用したData Pipeline を使用することもできますが、実行できるスクリプトの機能が制限されているため、PHPスクリプト、コードベース全体へのアクセス、EC2インスタンスをElasticBeanstalkクラスターの外部に置くこともできますが、その後は再度フェールオーバーすることはできません。

だからここに私が思いついたものがあり、明らかに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");
}

それで、これとそれがどのように動作するかを見てみましょう...すべてのEC2インスタンスで通常行うように、crontabからスクリプトを呼び出します。各スクリプトには最初にこれが含まれます(または、使用するたびに1つのファイルが含まれます)。これにより、ElasticBeanstalkオブジェクトが確立され、すべてのインスタンスのリストが取得されます。リスト内の最初のサーバーのみを使用し、一致するかどうかを確認し、一致する場合は継続し、一致しない場合は終了して終了します。チェックしましたが、返されるリストは一貫しているようです。技術的には、各インスタンスがスケジュールされたcronを実行するため、1分程度の一貫性があれば十分です。変更しても、それは重要ではありません。これは、その小さなウィンドウにのみ関連するためです。

これは決してエレガントではありませんが、私たちの特定のニーズに適合しました。追加のサービスでコストを増加させたり、専用のEC2インスタンスを用意したりする必要はなく、障害が発生した場合はフェイルオーバーします。 cronスクリプトは、SQSに配置されるメンテナンススクリプトを実行し、クラスター内の各サーバーの実行を支援します。少なくとも、これがニーズに合っている場合、代替オプションを提供できます。

-デイビー

12
user1599237

私はAWSサポートエージェントと話をしました。これが私たちが私のために働いた方法です。 2015年のソリューション:

Your_file_name.configを使用して、.ebextensionsディレクトリにファイルを作成します。構成ファイルの入力:

ファイル:
 "/etc/cron.d/cron_example":
モード:" 000644 "
所有者:root 
グループ:root 
 content :| 
 * * * * * root /usr/local/bin/cron_example.sh

 "/usr/local/bin/cron_example.sh":
モード: "000755" 
所有者:root 
グループ:root 
コンテンツ:| 
#!/ bin/bash 
 
 /usr/local/bin/test_cron.sh || exit 
 echo "Cron running at" `date` >> /tmp/cron_example.log
#1つのインスタンスでのみ実行するタスクを実行します... 
 
 "/usr/local/bin/test_cron.sh":
モード:" 000755 "
所有者:root 
グループ:root 
コンテンツ:| 
#!/ 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)}' `
 
#Auto Scaling Group名を見つけます。
 ASG =` aws ec2 describe-タグ--filters "Name = resource-id、Values = $ INSTANCE_ID"\
 --region $ REGION --output text | awk '/ aws:autoscaling:groupName/{print $ 5}' `
 
#グループの最初のインスタンスを検索
 FIRST =` aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ ASG\
 --region $ REGION --output text | awk '/ InService $/{print $ 4}' |並べ替え| head -1` 
 
#それらが同じかどうかをテストします。
 ["$ FIRST" = "$ INSTANCE_ID"] 
 
コマンド:
 rm_old_cron:
コマンド: "rm * .bak" 
 cwd: "/etc/cron.d"
 ignoreErrors:true 

このソリューションには2つの欠点があります。

  1. 以降のデプロイメントでは、Beanstalkは既存のcronスクリプトの名前を.bakに変更しますが、cronは引き続き実行します。これで、Cronが同じマシンで2回実行されます。
  2. 環境が拡大すると、いくつかのインスタンスが取得され、すべてがcronスクリプトを実行します。これは、メールショットが繰り返されるか、データベースアーカイブが複製されることを意味します

回避策:

  1. Cronを作成するすべての.ebextensionsスクリプトが、後続のデプロイメントで.bakファイルも削除することを確認します。
  2. 以下を実行するヘルパースクリプトを用意します。-メタデータから現在のインスタンスIDを取得します-EC2タグから現在のAuto Scaling Group名を取得します-そのグループ内のEC2インスタンスのリストをアルファベット順に取得します。 -そのリストから最初のインスタンスを取得します。 -ステップ1のインスタンスIDとステップ4の最初のインスタンスIDを比較します。cronスクリプトはこのヘルパースクリプトを使用して、実行する必要があるかどうかを判断できます。

警告:

  • Beanstalkインスタンスに使用されるIAMロールには、ec2:DescribeTagsおよびautoscaling:DescribeAutoScalingGroupsアクセス許可が必要です
  • から選択されたインスタンスは、Auto ScalingによりInServiceとして表示されます。これは、それらが完全に起動し、cronを実行する準備ができていることを必ずしも意味しません。

デフォルトのbeanstalkロールを使用している場合、IAMロールを設定する必要はありません。

8
Ken

Railsを使用している場合は、 whenever-elasticbeanstalk gem を使用できます。すべてのインスタンスまたは1つだけでcronジョブを実行できます。 1分ごとに「リーダー」インスタンスが存在することを確認し、存在しない場合は1つのサーバーを自動的に「リーダー」に昇格させます。 Elastic Beanstalkにはデプロイ中にリーダーという概念しかなく、スケーリング中はいつでもインスタンスをシャットダウンできるため、これが必要です。

[〜#〜] update [〜#〜]AWS OpsWorksの使用に切り替えて、このgemをメンテナンスしなくなりました。 Elastic Beanstalkの基本で利用できる以上の機能が必要な場合は、OpsWorksに切り替えることを強くお勧めします。

7
dignoe

Elastic Beanstalkでcronジョブを実行したくありません。複数のアプリケーションインスタンスがあるため、これにより競合状態やその他の奇妙な問題が発生する可能性があります。私は実際に 最近これについてブログに書いた (ページの4番目または5番目のヒント)。短いバージョン:アプリケーションによっては、SQSのようなジョブキューまたは iron.io のようなサードパーティソリューションを使用します。

6
jamieb

container_commandsの代わりにfilesを使用したより読みやすいソリューション:

ファイル:
 "/etc/cron.d/my_cron":
モード:" 000644 "
所有者:root 
グループ:root 
 content:| 
#デフォルトのメールアドレスを上書きします
 MAILTO = "[email protected]" 
#Symfonyコマンドを5分ごとに実行します(ec2-userとして) 
 */10 * * * * ec2-user/usr/bin/php/var/app/current/app/console do:something 
 encoding:plain 
 commands:
#Elastic Beanstalk 
 clear_cron_backup:
コマンドで作成されたバックアップファイルを削除:rm -f /etc/cron.d/watson.bak

この形式は、コマンドを実行するユーザーを指定するという点で、通常のcrontab形式とは異なります。

4
Tamlyn

2018年の私の1セントの貢献

正しい方法は次のとおりです(Django/pythonおよびDjango_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

commandsではなくcontainer_commandsにする必要があります

3
Ronaldo Bahia

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

2
Sebastien Horin

誰かが新しいリーダーが登場したとき、leader_onlyの自動スケーリングの問題について疑問に思っていました。コメントに返信する方法がわからないようですが、次のリンクを参照してください: http://blog.paulopoiati.com/2013/08/25/running-cron-in-elastic-beanstalk-自動スケーリング環境/

2
Random5000

ソリューションの完全な説明は次のとおりです。

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

1
poiati

これは、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の出力をデバッグできます。

これが確実に私たちを助けてくれるので、これが誰かを助けることを願っています!

0
foxybagga

スケーリング時に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

0
Dele

だから私たちはしばらくこれに苦労しており、AWS担当者との議論の後、私は最終的に私が最高のソリューションだと思うものを思いつきました。

Cron.yamlでワーカー層を使用することは、間違いなく最も簡単な修正方法です。ただし、ドキュメントで明確になっていないのは、これにより、実際に実行するために使用しているSQSキューのendにジョブが配置されることです。ジョブ。 cronジョブが時間に依存している場合(多くの場合)、キューのサイズに依存するため、これは受け入れられません。 1つのオプションは、cronジョブを実行するためだけに完全に独立した環境を使用することですが、それはやり過ぎだと思います。

リストの最初のインスタンスであるかどうかを確認するなど、他のオプションのいくつかも理想的ではありません。現在の最初のインスタンスがシャットダウン処理中の場合はどうなりますか?

インスタンス保護にも問題が発生する可能性があります-そのインスタンスがロック/フリーズした場合はどうなりますか?

理解することが重要なのは、AWS自体がcron.yaml機能を管理する方法です。 Dynamoテーブルを使用して「リーダー選出」を処理するSQSデーモンがあります。このテーブルに頻繁に書き込みます。現在のリーダーが短時間で書き込みを行っていない場合、次のインスタンスがリーダーとして引き継ぎます。これは、デーモンがSQSキューにジョブを起動するインスタンスを決定する方法です。

独自の機能を書き換えるのではなく、既存の機能を再利用できます。ここで完全なソリューションを見ることができます: https://Gist.github.com/dorner/4517fe2b8c79ccb3971084ec28267f27

これはRubyにありますが、AWS SDKを備えた他の言語に簡単に適合させることができます。基本的に、現在のリーダーをチェックし、状態をチェックして、良好な状態であることを確認します。現在のリーダーが良好な状態になるまでループし、現在のインスタンスがリーダーである場合、ジョブを実行します。

0
Cidolfas

ser1599237 からの回答の原則に基づいて、cronジョブをすべてのインスタンスで実行できるようにしますが、代わりにジョブの開始時に実行を許可するかどうかを決定し、別のソリューションを作成しました。

実行中のインスタンスを確認する(およびAWSキーとシークレットを保存する)代わりに、すべてのインスタンスから既に接続しているMySQLデータベースを使用しています。

マイナス面はなく、プラス面のみ:

  • 追加のインスタンスや費用はありません
  • 堅実なソリューション-二重実行の可能性なし
  • スケーラブル-インスタンスがスケールアップおよびスケールダウンされると自動的に機能します
  • フェイルオーバー-インスタンスに障害がある場合に自動的に機能します

または、データベースの代わりに、一般的に共有されているファイルシステム(NFSプロトコル経由で AWS EFS など)を使用することもできます。

次のソリューションはPHP framework 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`)
)
0
TheStoryCoder

Phpファイルをcronで実行する必要があり、NATインスタンスを設定した場合、cronjobをNAT instanceそして、wgetを介してphpファイルを実行します。

0
prasoon