web-dev-qa-db-ja.com

cronジョブマイクロサービス

マイクロサービスの束で作られたアプリケーションを実装しています。それぞれがかなり単純で、独自のタスクに焦点を当てています。それらの2つをService AService Bと呼びましょう。どちらもNodeJに実装されており、Rest APIを公開しています。次に、いくつかのcronジョブを実行する必要があります(1 m間隔で実行するもの、5 m、1時間で実行するものなど)で、あるサービスから別のサービスにデータを渡す必要があります。たとえば、Service Aからのデータが必要です。外部APIを呼び出し、データを処理してPOSTService Bに送信します。

enter image description here

この例ではTask Masterと呼ばれる別のマイクロサービスを使用することを考えました。これにより、このcronジョブとその他すべて(アプリケーション内のすべてのサービス)が実行され、すべてのcronジョブのマスターになります。

  1. これは悪い考えですか? cronジョブ専用の1つのマイクロサービス?そしてすべてのcronジョブ?
  2. これを実装する最良の方法は何でしょうか?それは別のNodeJsアプリですか?
1
Matis

これはかなり一般的なパターンです。あなたが説明したことの多くを達成するための既存のソフトウェアがあるのに十分一般的です。 kubernetes cronjobs 、または セロリ定期タスク などを確認してください。ほとんどのサーバーレスフレームワークは、定期的なスケジューリングもサポートしています。独自のものを作成する前に、既存の実装を徹底的に見直します。

1
Karl Bielefeldt

ご覧ください Apache Airflow 。また、ほとんどのサーバーレスフレームワークには、それを達成するための機能があります。たとえば、ユーザーがPythonおよびAWS Lambdaという名前のZappaというフレームワークを使用しているとします。このフレームワークには、ジョブをスケジュールするための設定があります。

非常に複雑なジョブをスケジュールする別の方法は、 Jenkins をいくつかのプラグインで使用して、いくつかの単純なパイプラインを構築することです。

1
mcrrnz

マイクロサービス環境では、サービス間でデータを同期する必要があります。それにはさまざまなオプションがあります。 Cronの仕事を持つことは間違いなくアプローチの1つです。他のアプローチとしては、ETL、サービスが他のサービスから必要なデータを定期的にフェッチするサービス、メッセージングまたはPub/Subメカニズムなどがあります。他の方法や同期が考えられますが、これらは最も一般的で効果的な方法のようです。仕事をする方法が複数ある場合は、さまざまなアプローチの長所と短所を比較するとよいでしょう。

[〜#〜] etl [〜#〜]サービスAのデータベースを直接読み取り、データを変換してサービスBのデータベースに挿入/更新するように構成できるツールがあります。ツールのクラスはETL(Extract Transform And Load)と呼ばれます

  1. (利点)統合するために最小限の作業のみを必要とする市販の製品が多数あります
  2. (欠点)これで、別のアプリケーション(ETL)がサービスAとサービスBのデータベースのスキーマを認識します。これにより、サービスAとサービスBの独立した配備機能が低下します。サービスAのデータベースのスキーマを変更すると、再配備が必要になります。サービスAとETLの。 ETLジョブは、データベースのスキーマの変更に抵抗を引き起こします。
  3. (短所)市場で入手可能なツールは一般的に少し高価です

Cronジョブ設計したcronジョブは、いくつかの点でETLに似ています。ただし、大きな違いは、データベーススキーマではなく、アプリケーションによって指示される言語を使用するアプリケーションとの仕事上の話です。

  1. (利点)cronジョブは独立して展開可能です。ただし、アプリケーションコントラクトが破損しないように注意する必要があります。
  2. (利点)実装が非常に簡単です。
  3. (短所)通常、サービスはドメインに基づいて作成されます。各サブドメインは、ドメインの機能を促進するサービスとして編成されています。これで、cronジョブにはさまざまなサービスのデータニーズに関する情報が含まれます。時間の経過とともに、cronジョブの数が増加したり、cronジョブのコードサイズがますます大きくなる可能性が高くなります。いずれにしても、cronジョブの維持が難しくなります。
  4. (欠点)cronジョブの実行中は、負荷が原因でサービスの応答が遅くなる可能性があります。

サービスAから定期的にデータをフェッチするサービスB

  1. (利点)サービスは独立して展開可能です。ただし、アプリケーションコントラクトが破損しないように注意する必要があります。
  2. (利点)実装が非常に簡単です。
  3. (利点)サービスBのすべての要件が1つのリポジトリにコード化されます。必要なデータはServiceのリポジトリにもコーディングされていますが、
  4. (短所)データソース(ここではサービスA)とのカップリングがある
  5. (短所)データをフェッチするためにサービスBをトリガーするのは少し難しいかもしれません
  6. (短所)サービスがデータをフェッチしているときに、負荷が原因で応答が遅くなる可能性があります。

Messagin/Pub-SubメカニズムサービスAは、イベント/メッセージをkafka、RabbitMQ、Azure Service Busなどのメッセージブローカー/イベントシステムに発行します。サービスBはこれらのイベント/メッセージをリッスンします。イベント/メッセージには、サービスBに必要なすべてのデータを含めることができます。または、サービスBがサービスAにクエリを発行して、イベント/メッセージの受信に関する追加のデータを取得できます。

  1. (利点)サービスAとサービスBは高度に分離されている
  2. (利点)イベント/メッセージングインフラストラクチャは、ビジネスロジックがまったくない(あまりない)とは言えません。
  3. (利点)システムを適切に実装すると、応答性が常に良好になります。
  4. (短所)システムの実装は複雑です。
  5. (欠点)Azure Function、AWS Lambda、KNativeなどのサーバーレステクノロジーを使用してサービスBを実装することは困難です。サーバーレステクノロジーとイベント/メッセージングインフラストラクチャのバインディングの可用性に依存するのは困難です。

個人的には、サービスBを開始してサービスAから定期的にデータをフェッチし、システムの複雑さが増すにつれてイベントメカニズムに移行することを好みます

ここで達成しようとしているのはコンテキストマッピングです。各マイクロサービスはコンテキストを表し、データをあるコンテキストから別のコンテキストに移動(マッピング)しています。理想的には、この通信を非同期にして、コンテキスト間のデータが最終的に整合するようにする必要があります。トランザクションの一貫性が必要な場合は、コンテキスト/マイクロサービスの境界を再検討する必要があります。

コンテキストマッピングを実現するにはいくつかの方法があります。メッセージバスを使用できます。ServiceAはServiceBが必要とするデータを含むメッセージを発行し、ServiceBはこのメッセージにサブスクライブしてデータを受信します。ただし、これにはまだ導入されていない場合があり、実装にかなりの労力を要するインフラストラクチャの使用が含まれます。

このコンテキストマッピングを実現する別の方法は、ポーリングを使用することです。 ServiceBは、ServiceAから必要なすべてのデータについてServiceAをポーリングできます。このポーリングは別のプロセス(AWS Lambda、Azure Function、またはcronジョブの可能性があります)にすることができますが、それでもマイクロサービスServiceBの一部になります。結局のところ、ServiceAのデータを必要とするのはServiceBです。あなたがそれを説明したように、ServiceAはServiceBから何も必要としません。ここでの照明はマイクロサービスは複数のプロセスになる可能性があるだと思います。これまでに説明したことを踏まえると、これはシナリオに最も適したコンテキストマッピング戦略であると思います。 TaskMasterサービスは必要ありません。必要なデータの取得を処理するServiceBの構成プロセスのみです。

他にもコンテキストマッピング戦略があります。詳細については、Vaughn VernonのIDDDを参照してください。

1
Yuli Bonner