web-dev-qa-db-ja.com

REST APIを介して公開される重いタスク

私が現在検討しているシステムの一部は、REST APIを使用していくつかのスレーブノードを呼び出すマスターノードで構成されています。

スレーブノードは世界中のさまざまなサーバーに分散しており、マスターはサーバー上で毎分ジョブを実行できます。 API呼び出しの結果は、約50秒以上かかりません。マスターとスレーブはどちらもnode.jsに基づいており、スレーブはExpressフレームワークを使用しています。

参考までに、ここに簡略化した図を示します。 master communicating with three slaves using REST

マスターノードがすべてのスレーブノードにリクエストを送信すると、すべてのリクエストが完了する(またはタイムアウトする)まで待機し、結果のデータを処理します。

このStackOverflowの投稿 によると、Webアプリケーションが数分待ってから応答を返すことはできません。ジョブが1分未満で数秒を超える場合、ブロッキングREST呼び出しをこのように使用するのが適切ですか?これが非-パブリックAPI、スレーブの障害/利用不可は依然としてマスターノードにとって有用なデータと見なされているという事実、およびマスターはすべてのスレーブからのデータなしでは処理できないという事実。

4
J. Pinkman

このStackOverflowの投稿によると、Webアプリケーションが応答を返す前に数分待つことは問題です

あえて言うとWeb開発の主要な部分では便利ではありません。問題は、接続を維持することではなく、サーバー側でリソースをロックすることです。スレッドの作成、実行、保持にはコストがかかります。主にメモリの面で。問題は、リソースをすぐに解放しないと、より多くのスレッドを割り当てるサーバーの容量が減少するため、スループットが低下することです。

幸いにも、NodeJSはモノスレッドであり、 リソースをロックせず、アイドル状態を維持しない であるため、これは問題になりません。強制しない限り。応答を待機するように強制すると、非ブロッキングのパフォーマンスIOプロセスが非パフォーマンスのプロセスになり、プロセスがブロックされます。NodeJSの性質とその1つを損なうもの最も価値のある機能。

同時に非同期でイベントを呼び出し、順序はまったく関係ありません

次に、非同期的に応答を待ちます。この状況は、メッセージに基づくエンタープライズ統合設計パターンに適しています(IMO)。簡単に要約すると、次のようなものになる可能性があります。

  • マスターは新しいトランザクションを開始し、それに 相関識別子またはトランザクションIDを提供します
  • マスターは、トランザクションに関与する各ワーカー(またはブローカー)にメッセージを送信します。メッセージには、トランザクションID、指示、およびレポート先のエンドポイントが含まれます
  • wrokerはジョブを実行し、レポートエンドポイントへの要求によってレポート(結果)をマスターに送信します。

例えば:

{   
    "headers":{ 
      "Transaction-ID":"xxxx", 
      "Transaction-URI":"proto://Host:port/endpoint/transaction/xxxx"
      "Created":"yyyy-MM-ddTHH:mm:ssZ" 
    }, 
    "body":{ ... }     
}

スレーブの障害/使用不可は依然としてマスターノードにとって有用なデータと見なされるという事実、およびマスターはすべてのスレーブからのデータなしでは続行できないという事実。

2つのオプションがあります。

  1. マスターを不注意にしてください。すべてのスレーブが応答するのにどれだけ時間がかかるかは関係ありません。最終的にすべての応答を収集します。

  2. トランザクションを有効期限切れにします。タイムアウトで設定します。

-API呼び出しの結果は約50より長くかかりません-

すでにお持ちのようです。トランザクションが期限切れになると、マスターはトランザクションをfinished/unfinishedに設定し、状態を更新しなくなります。労働者が遅れて反応した場合は、それも追跡できます。

レポートエンドポイントidempotentを作成した場合、ワーカーは時間どおりに応答するかどうかを気にしないでください。マスターは気になります。

まとめると、すべてのプロトコルはかなりfire-and-forgetであり、これは(単純化されすぎて)NodeJSが得意なことです。

これは非公開のAPIであることを考慮する

関係ありません

マスターは@ Hans-MartinMosnerが示唆するように続行できます。トランザクション結果のフェッチに進む前にクライアントが待機するための見積もり(60秒?)とともにクライアントにHttp Status 202 Createdで応答できます。

トランザクションを永続化すると、クライアントがトランザクションの状態を追跡できるようにすることもできます。 「確認済み」から「処理中」および「正常終了」または「エラー終了」まで。

0
Laiv

ここで重要な洞察は、ジョブのアクティブ化を有効期間の長いリソースとして扱うことです。

同様の状況で、POSTメソッドを使用してジョブの作成を実装しました。このメソッドは、新しく作成されたジョブの場所を含む「202 Accepted」応答を返します。

その後、クライアントは、完了するまでこのジョブのステータスをポーリングできます。

不当に頻繁なポーリングや不必要な遅延を回避するために、ポーリング要求にHTTP Preferヘッダーとwait属性を使用していますが、これは適度に機能します。私がRFCの作成者が意図した使用パターンに完全に収まっているかどうかは判断できませんが、これは私がコード化したクライアントとサーバーを使用した内部アプリケーションであるため、これは重要ではありません。

8