2017-11-10 19 views
3

お客様は、毎月レポートを作成したいと考えています。@monthly cronジョブが信頼できない

以前は、このタスクに@monthly cronジョブを使用していました。

は、しかし、これは信頼できません。

  1. サーバがダウンし、この分である可能性があります。 Cronはこれらのジョブを再実行しません。
  2. サーバが起動している場合、この瞬間にデータベースに到達できない可能性があります。
  3. サーバが稼働していてDBが稼働している場合、到達不能なサードパーティシステムが存在する可能性があります。
  4. ソフトウェアバグが存在する可能性があります。

レポートは毎月作成されることを確認するにはどうすればよいですか?

これは、移動駒と考慮すべき結果として、オプションの数が多すぎジャンゴベースのWebアプリケーション

+0

これを行うには、レポートの作成を成功させるための信頼できる方法が必要です。あなたのデータベースに成功した試みを記録する 'ReportCreationLog'モデルのようなものを考えましたか?そうすれば、すべての基準が満たされるようにすることができます。 – Cole

+0

@Coleはい、あなたは正しいです。私はログが必要ないと思う。結果がすでに利用可能かどうかを確認することができました。 – guettli

答えて

1

条件をテストし、必要な操作をすべて実行するスクリプトを作成する必要があります。

if is_work_finished_less_then_month_ago(): 
    return 
else: 
    try: 
     generate_normal_report() 
    except some_error as e: 
     report_about_error(e) 

その後、1時間または1日ごとに実行します。

error_reportsが多すぎる場合は、report_about_error()の方法で同じことをしてください:最後にレポートを送信したことを確認し、頻繁に送信しないでください。

+0

これは等価性に関連していますか?私は一度これをセロリの文書で読んでいます:http://docs.celeryproject.org/en/latest/glossary.html#term-idempotent – guettli

+1

@guettliはい、結果を変えずに何度も呼び出すことができる関数です。実際には、意図しない効果を伴わずに何度も何度も繰り返すことができますが、必ずしも純粋な意味では副作用がないわけではありません。 –

+0

はい、私はセロリを使うことができました。しかし、私はこの単純な解決策が好きです。私はこの仕事を6時間ごとに実行することができました。真夜中に失敗した場合は、6時に再実行されます。 – guettli

1

です。しかし、問題1は、成功を追跡するために何らかの外部的な方法が必要であることを意味します(そうでなければ、サーバータスクのためのオプション(bashスクリプトなど)はレポート作成が成功するまでN回再試行し、

JenkinsやSOS Berlinのようなサードパーティ製のスケジューラを利用することで、さまざまなニーズに対応できます。

シンプルなソリューションをお探しの場合は、cronを使用してレポートスクリプトを何度も実行するようにスケジューリングすることができます(月末に数時間ごとに1時間ごとなど)生成され、正常に送信されました(これは、ファイルを作成してその存在をチェックするか、データベースに値を書き込むなどの単純な操作です)。

+0

私は「より単純な解決策」に完全に同意します。しかし、ソフトウェアのバグがあると、複数のレポートが送信または作成される可能性があります。この問題には、1)バグのない正しいソフトウェアを書く、または2)ソフトウェアを書き込まない、という2つのソリューションしかありません。 –

6

は、セロリ、ビートがスケジューラである

まともなスケジューラを使用します。定期的にタスクを開始し、クラスタ内の使用可能なワーカーノードによって実行されます。

レポート機能ジョブを使用して定期タスクを作成します。ジョブが失敗すると、設定した再試行ポリシーに従ってセロリが再試行されます。

Celery doc - Periodic Tasks

+0

私はセロリで一度働いた。それは大きくて複雑に感じました。機能が少ないツールは、私の現在のユースケースでは良いかもしれません。それにもかかわらず、この答えに感謝します。私は投票した。 – guettli

+0

upvoteに感謝します。私はいつもセロリを使い、大丈夫だと私はもうあなたを助けません。 –

+1

@guettli最初にパッケージが設定され、オプションの[デーモン化](http://docs.celeryproject.org/en/latest/userguide/daemonizing.html)が実行されていても、実際は大きく感じるかもしれませんが、 Djangoプロジェクトのコードは非常に短いです。 – ppython

1

簡単な方法は、スクリプトは、最初のレポートの可用性をチェックし、報告書が利用できない場合にのみ、レポートを生成するようなヘルパーを書くことができるということです。

次に、月のその日に1時間ごとにスクリプトを実行するようにスケジュールを設定します。

if [[ -f <report_name> ]] 
then 
    echo "report exists" 
    exit 1 
else 
    echo "run generate report script" 

crontabエントリを(毎月28日にすべての時間を実行する)::

は、次のようにスクリプトを変更

0 0-23 28 * * <name_of_helper_script> 
1

のcronはあなたが求めているものを行うことができません。あなたのDjangoアプリでcronのようなタスクを開始するのは、Djangoが作成されたものではなく、アプリケーションが誤動作している場合など、すべての端のケースを処理して失敗した場合にのみ動作します。エラー処理のウサギ・ホール、状態管理および並行性の考慮事項。

私は2つのオプションのいずれかを示唆している:(とにかく

  • のcronでジョブキックオフを、しかし、報告書が何らかの理由で生成されなかった場合に通知していることを確認するために、Nagiosのチェックを書き、手動でそれらのまれなケースを扱う)。
  • Airflowまたはスケジュールされたタスクのスケジューリング、監視、再試行、およびログ処理を目的として作成されたその他のフレームワークを使用してください。

前者は、これは本当に一回限りのジョブである場合、あなたが望むものです。後者は、あなたのようにもっと多くのタスクがある場合は、より良いです。

+0

Apache Airflowは非常に豊富な機能を備えています。私はそれが有効なユースケースを持っていると思います。私の場合、それはあまりにも大きいです。 – guettli

+1

この場合、私は単純な解決策としてcronに行き、実際にレポートが生成されるのを監視することをお勧めします。これは、失敗しないシステムを設計するよりはるかに簡単です。 –

+0

"idempotence"という言葉を考えた後、毎時間スクリプトを呼び出すことができました。レポートが存在する場合は、何もしません。そうでない場合は、出力が作成されます。 – guettli

関連する問題