12

私のアプリケーションはWebサービス要求を行います。プロバイダーが処理するリクエストの最大レートがあるので、それらを抑制する必要があります。

アプリが単一のサーバーで実行されていたとき、私はアプリケーションレベルでそれを実行していました。これは、これまでに行われたリクエストの数を追跡し、現在のリクエストが最大許容負荷を超えた場合に待機するオブジェクトです。

現在、単一のサーバーからクラスターに移行しているため、実行中のアプリケーションのコピーが2つあります。

  • 2つのノードを組み合わせると許容負荷を超える可能性があるため、アプリケーションコードで最大負荷をチェックし続けることができません。
  • 他のノードがアイドル状態の場合、最初のノードがより多くのリクエストを送信できるため、各サーバーの負荷を単純に減らすことはできません。

これはJavaEE5環境です。アプリケーションが送信するリクエストを抑制するための最良の方法は何ですか?

4

6 に答える 6

6

すでにJavaEE環境にいるので、JMSキューに基づいてWebサービスへのすべての要求を処理するMDBを作成できます。アプリケーションのインスタンスは、リクエストをキューに送信するだけで、MDBがリクエストを受信して​​Webサービスを呼び出します。

キューは実際には、Webサービスへの同時アクセスを制限する適切な数のセッションで構成できるため、スロットリングはキュー構成を介して処理されます。

結果は、別のキュー(またはアプリケーションインスタンスごとのキュー)を介して返すことができます。

于 2010-02-24T21:47:30.963 に答える
2

これを行う多くの方法:サーバーへの「トークン」の受け渡しを担当する「調整エージェント」がある場合があります。各「トークン」は、タスクなどを実行するための許可を表します。各アプリケーションは、呼び出しを行うために「トークン」を要求する必要があります。

アプリケーションがトークンを使い果たすと、Webサービスに再度アクセスする前に、さらに要求する必要があります。

もちろん、Webサービスへの同時実行性のために、各アプリケーションが行う各呼び出しのタイミングに関する要件がある場合、これはすべて複雑になります。

メッセージングフレームワークとしてRabbitMQを信頼できます。Javaバインディングが利用可能です。

于 2010-02-24T21:22:46.677 に答える
2

Nノードは通信する必要があります。さまざまな戦略があります。

  • ブロードキャスト:各ノードは、コールをマッキングしていることを他のすべての人にブロードキャストし、他のすべてのノードはそれを考慮に入れます。ノードは等しく、個々のグローバルカウントを維持します(各ノードは他のすべてのノードの呼び出しを認識しています)。
  • マスターノード:1つのノードは特別であり、そのマスターと他のすべてのノードは、呼び出しを行う前にマスターに許可を求めます。グローバルカウントを知っているのはマスターだけです。
  • 専用マスター:マスターと同じですが、「マスター」はそれ自体で呼び出しを行わず、呼び出しを追跡する単なるサービスです。

後で拡張する予定の高さに応じて、どちらかの戦略が最適な場合があります。2つのノードの場合、最も単純なノードがブロードキャストされますが、ノードの数が増えると、問題が発生し始めます(実際にWS要求を行うよりも、ブロードキャストとブロードキャットへの応答に多くの時間を費やすことになります)。

ノードがどのように通信するかはあなた次第です。TCPパイプを開くことができ、UDPをブロードキャットすることができ、この目的のためだけに本格的なWSを実行することができ、ファイル共有プロトコルを使用することができます。何をするにしても、あなたはもはやプロセスの中にいないので、分散コンピューティングのすべての誤りが当てはまります。

于 2010-02-24T21:27:26.190 に答える
2

Beanstalkdを使用して、リクエスト(ジョブ)のコレクションを定期的にチューブ(キュー)に送り込むことをお勧めします。それぞれに適切な遅延があります。任意の数の「ワーカー」スレッドまたはプロセスが次のリクエストが利用可能になるのを待ち、ワーカーが早期に終了した場合、次のリクエストを受け取ることができます。欠点は、ワーカー間に明示的な負荷分散がないことですが、キューからの要求の分散は十分に分散されていることがわかりました。

于 2010-02-25T01:51:07.803 に答える
1

これは興味深い問題であり、解決の難しさは、スロットルをどの程度厳しくしたいかによって異なります。

これに対する私の通常の解決策はJBossCacheです。これは、JBoss AppServerにパッケージ化されていることもありますが、タスクをかなりうまく処理することも理由です。これを一種の分散ハッシュマップとして使用し、さまざまな粒度で使用統計を記録できます。更新は非同期で実行できるため、処理速度が低下することはありません。

JBossCacheは通常、ヘビーデューティーの分散キャッシングに使用されますが、これらの軽量のジョブにも使用されます。これは純粋なJavaであり、JVMをいじくり回す必要はありません(Terracottaとは異なります)。

于 2010-02-24T23:21:58.587 に答える
1

Hystrixは、あなたが説明しているシナリオとほぼ同じように設計されています。各サービスのスレッドプールサイズを定義して、同時リクエストの最大数を設定し、プールがいっぱいになるとリクエストをキューに入れることができます。各サービスのタイムアウトを定義することもできます。サービスがタイムアウトを超え始めた場合、Hystrixは、サービスが元に戻る機会を与えるために、そのサービスへのそれ以上のリクエストを短期間拒否します。Turbineを介してクラスター全体をリアルタイムで監視することもできます。

于 2014-09-25T21:39:02.387 に答える