5

私はElastic BeanstalkでDjangoアプリケーションの毎日のタスクを設定しようとしています。セロリのビートはDjangoの定期的なタスクのための解決策ですが、負荷分散された環境には適していないため、これを設定するための受け入れられた方法はありません。エラストンBeanstalkのDjangoでの定期的な作業(おそらくセロリの拍子で)

私は、1つのインスタンスのみを実行するためにleader_only = Trueでセロリのビートを設定するなどのいくつかの解決策を見たことがありますが、それは単一障害点を残します。私はセロリの多くのインスタンスがロックを使用して1つのタスクだけを通過することを可能にする他のソリューションを見てきましたが、失敗したインスタンスが再起動されない限り、私が見た別の提案は、セロリビートを実行するための別のインスタンスを持つことですが、失敗した場合に再起動する方法がない限り、これはまだ問題になります。

この問題の解決策はありますか?スケジューラのベビーシッターをしなくても、私の仕事がしばらく後には実行されていないことに気づかずに済むはずです。

+0

リーダーインスタンス上でそれを実行している問題は何ですか?そのインスタンスがヘルスチェックに失敗した場合、別のインスタンスがプロモートされます。 – Gustaf

+0

celerybeatが失敗した場合、ヘルスチェックを失敗させる方法は? –

+0

これは、複数のインスタンスのロードバランシングを実行している場合に、専用のロギング/監視マシンをセットアップしたり、サービスを購入したりすることを考慮する必要があります。 Amazonは1つを提供します。私はSentryが好きです。 –

答えて

0

私はmanagement commandをcronで実行することをお勧めします。

この方法を使用すると、完全なDjango ORM、すべてのメソッドなどを操作できます。あなたのスクリプトをtry/exceptにラップすると、電子メール通知、Sentryのような外部ログシステム、DBに直接ログなどの任意の方法で失敗を記録するオプションがあります。

私はcronを実行するスーパーバイザーとそれはうまくいく。それはあなたを失望させない、長年にわたってテストされたツールに依存しています。

最後に、バッチジョブが実行されているか、現在負荷分散されているDjangoのインスタンスが複数ある環境で実行されているかどうかを追跡するデータベースシングルトンを使用しても、それについて少し不気味です。 DBは、DBが処理されているかどうかを伝える非常に信頼できる手段です。

cronに関する1つの厄介なことは、Djangoに必要な環境変数をインポートしないことです。私はこれを単純なPythonスクリプトで解決しました。

起動時に必要な環境変数などを含めてcrontabを書き込みます。この例はEBS上のUbuntu向けですが、関連性があります。

#!/usr/bin/env python 

# run-cron.py 
# sets environment variable crontab fragments and runs cron 

import os 
from subprocess import call 
from master.settings import IS_AWS 

# read django's needed environment variables and set them in the appropriate crontab fragment 
eRDS_HOSTNAME = os.environ["RDS_HOSTNAME"] 
eRDS_DB_NAME = os.environ["RDS_DB_NAME"] 
eRDS_PASSWORD = os.environ["RDS_PASSWORD"] 
eRDS_USERNAME = os.environ["RDS_USERNAME"] 

try: 
    eAWS_STAGING = os.environ["AWS_STAGING"] 
except KeyError: 
    eAWS_STAGING = None 

try: 
    eAWS_PRODUCTION = os.environ["AWS_PRODUCTION"] 
except KeyError: 
    eAWS_PRODUCTION = None 

eRDS_PORT = os.environ["RDS_PORT"] 

if IS_AWS: 
    fto = '/etc/cron.d/stortrac-cron' 
else: 
    fto = 'test_cron_file' 

with open(fto,'w+') as file: 
    file.write('# Auto-generated cron tab that imports needed variables and runs a python script') 

    file.write('\nRDS_HOSTNAME=') 
    file.write(eRDS_HOSTNAME) 
    file.write('\nRDS_DB_NAME=') 
    file.write(eRDS_DB_NAME) 
    file.write('\nRDS_PASSWORD=') 
    file.write(eRDS_PASSWORD) 
    file.write('\nRDS_USERNAME=') 
    file.write(eRDS_USERNAME) 
    file.write('\nRDS_PORT=') 
    file.write(eRDS_PORT) 
    if eAWS_STAGING is not None: 
     file.write('\nAWS_STAGING=') 
     file.write(eAWS_STAGING) 
    if eAWS_PRODUCTION is not None: 
     file.write('\nAWS_PRODUCTION=') 
     file.write(eAWS_PRODUCTION) 

    file.write('\n') 

    # Process queue of gobs 
    file.write('\n*/8 * * * * root python /code/app/manage.py queue --process-queue') 
    # Every 5 minutes, double-check thing is done 
    file.write('\n*/5 * * * * root python /code/app/manage.py thing --done') 
    # Every 4 hours, do this 
    file.write('\n8 */4 * * * root python /code/app/manage.py process_this') 
    # etc. 
    file.write('\n3 */4 * * * root python /ode/app/manage.py etc --silent') 
    file.write('\n\n') 

if IS_AWS: 
    args = ["cron","-f"] 
    call(args) 

そしてsupervisord.conf中:

[program:cron] 
command = python /my/directory/runcron.py 
autostart = true 
autorestart = false 
関連する問題