本当の質問に入る前に、いくつかの背景:
私はいくつかの異なるモジュールで構成されるバックエンドアプリケーションに取り組んでいます。現在、各モジュールはコマンドラインJavaアプリケーションであり、「オンデマンド」で実行されます(詳細は後で説明します)。
各モジュールは「ステップ」であり、データフローと考えることができるより大きなプロセスの一部です。最初のステップでは、外部ソースからデータファイルを収集し、それらをいくつかのSQLデータベーステーブルにプッシュ/ロードします。次に、さまざまな条件とイベント(タイミング、DB内のデータの存在、Webサービス/ Webインターフェイスを介して行われるメッセージと詳細)に基づいて、(1つ以上の)DBテーブルからデータを取得し、それらを処理します。それらを別のテーブルに書き留めます。ステップは3つの異なるサーバーで実行され、3つの異なるDBからデータを読み取りますが、単一のDBにのみ書き込みます。目的は、データを集約し、メトリックと統計を計算することです。
現在、各モジュールは定期的に実行されます(最初のモジュールの数分/時間から、チェーンの最後の数日まで、より多くのデータを集約する必要があるため、それらが利用可能になるまで「より長く」待機する必要があります)。 cronjob。モジュール(現在はJavaコンソールアプリケーション)が実行され、指定された日時ウィンドウ内の新しい未処理の情報がないかデータベースをチェックし、そのジョブを実行します。
問題:それは機能しますが、..私はそれを拡張して維持する必要があり、このアプローチはその限界を示し始めています。
- 私は「ポーリング」に頼るのは好きではありません。以前のモジュールの情報は、必要な情報が利用可能になったときにチェーンの下流にある他のモジュールに「伝える」のに十分であり、続行できることを考えると、無駄です。
- それは「遅い」です。データが到着し、前のモジュールによって処理されていることを確認する必要があるため、チェーンの下位のモジュールには数日間の遅延があります。したがって、すべてのデータが確実に得られるまで、これらのモジュールを「停止」します。新しい追加には、いくつかのメトリックのリアルタイム(難しいことではありませんが、「できるだけ早く」)の計算が必要です。非常に良い例は、ここで、バッジを使用してSOで何が起こるかです。:)私は本当に似たものを入手する必要があります。
2番目の問題を解決するために、「部分的」または「漸増的」計算を導入します。関連する情報のセットがある限り、それを処理します。次に、他のリンクされた情報が到着したら、差を計算してそれに応じてデータを更新しますが、他の(依存する)モジュールにも通知する必要があります。
質問)
-1)それを行うための最良の方法はどれですか?--2)関連:関連データが利用可能であることを他のモジュール(私の場合はJava実行可能ファイル)に「通知」するための最良の方法はどれですか?
私は3つの方法を見ることができます:
- 他の「非データ」テーブルをDBに追加します。このテーブルには、各モジュールが「ねえ、私はこれを実行し、使用可能です」と書き込みます。cronjobが別のモジュールを開始すると、テーブルを読み取り、サブセットxxxを計算できると判断して実行します。等々
- DBテーブルの代わりに、ZeroMQなどのメッセージキュー(または@mjnが提案するようなApache Camel)を使用します
DBテーブルの代わりに、RedisなどのKey-Valueストアを使用する
編集:キューに基づくアプローチが進むべき道であると確信しています。完全を期すために「テーブル+ポーリング」オプションを追加しましたが、これは気を散らすものにすぎないことを理解しています(明らかに、誰もが「はい、キューを使用します」と答えます。 、ポーリングは悪です」-そして当然のことながらそうです!)。では、質問を次のように言い換えます。Redisの ようなpub / subを備えたKey-ValueストアよりもMQを使用することの長所/短所は何ですか?
- 3)cronjobを完全に取り除くのに役立つ解決策はありますか?
編集:特に、場合によっては、それは次のことを意味します:「時間」でメッセージを公開できるようにするメカニズムが一部のMQおよび/またはKey-Valueストアにありますか?「1日で届ける」みたい?永続性と「ほぼ1回」の配信保証により、明らかに
- 4)このメッセージ(イベント?)ベースのソリューションを集中型サービスとして構築し、サーバーの1つでデーモン/サービスとして実行する必要がありますか?
- 5)サブスクライバーをオンデマンドで開始するというこのアイデアを放棄し、各モジュールをデーモン/サービスとして継続的に実行する必要がありますか?
- 6)長所と短所はどれですか(信頼性、単一障害点とリソースの使用量および複雑さ...)?
編集:これは私が最も気にかけているビットです:MSMQアクティベーションと同様に、キュー内のメッセージに基づいて「モジュール」をアクティブ化するためにそれ自体を「キューに入れ」たいと思います。それは良い考えですか?Javaの世界でそれを行うものはありますか?それを自分で実装する必要がありますか(MQまたはRedisを介して)、または各モジュールをデーモンとして実行する必要がありますか?(一部の計算が通常バーストで発生する場合でも、2時間の処理とそれに続く2日間のアイドリング?)
注:重いコンテナ/ EJBを使用できません(Glassfishなどは使用できません)
編集:ラクダも私には少し重すぎるようです。リソースと開発の複雑さの両方の観点から、ここで本当に軽いものを探しています