1

環境: Webphere 6、Solaris ボックス、シック クライアント、Java Web アプリ。

リクエストの数は 400 ~ 600 です。サーバーへのリクエストごとに、15 の異なる Web サービスを同時にリクエストするために 15 のスレッドを作成し (Java ExecutorService を使用)、すべての応答データをグループ化してユーザーに送り返します。150 ~ 170 人近くのユーザーで負荷テストが失敗します。これらの Web サービスにサービスを提供する DB で CPU とメモリのスパイクが見られ、最終的には非常に短時間でアプリ サーバーもクラッシュします。Web サービスの応答時間は、最大 10 ~ 12 秒、最小 4 ~ 6 秒です。DB の接続プーリング サイズは 40 です。

150 のリクエストで 150*15=2250 のスレッドが作成され、アプリ サーバーのリソースが急増してクラッシュしたと想定しています。したがって、アプリサーバーのスレッドプールを使用し、threadCount を 100 に設定したいと考えています (適切な数値ではない可能性があります..)。私を悩ませていることの 1 つは、100 スレッドで、最初の 6 (6*15 = 90) 要求と 7 番目の要求の 10 呼び出しを処理できることです。次のリクエストは、スレッドを戻すために 10 ~ 15 秒待機する必要があり、その後、独自の Web サービス呼び出しのためにさらに 10 ~ 15 秒待機する必要があります。このアプローチは良いですか?

もう 1 つのアイデアは、Websphere で提供される非同期 Bean です。どちらが私の要件に合っていますか。

提案してください!!。1 つの Web サービスを次々と呼び出すと、合計で 15*(各リクエストに 4 秒としましょう) = 60 秒かかります。これは非常に悪いことです。したがって、webserices をまとめて呼び出すことが、私がやりたいことです。

4

1 に答える 1

1

アプリケーション サーバーでスレッドを管理することはお勧めしません。EJB を使用している場合、仕様ではそれが許可されていません

キャッシュ ソリューションを使用してパフォーマンスを向上させてみませんか? 最初のいくつかのリクエストは遅くなりますが、キャッシュがホットになるとすべてが非常に高速になります。

データのキャッシュが実行できない場合、1 つの要求を複数のスレッドに分割するのではなく、サーバーに対して複数の要求を行うようにクライアントを変更するのはどうでしょうか? 各メソッドが 1 つの Web サービスを呼び出すように、Web アプリケーションを変更する必要があります。クライアントは、現在のページに必要な各メソッドを (並行して) 呼び出し、最終結果を組み立てます (必要に応じて、部分的な結果を表示することもできます)。これを行うことで、並行して作業を行い、仕様に違反することはありません。

サーバーに次のようなものがあるとします。

public Result retriveData(Long id) {
   Result myResult = new Result();
   //...
   //do some stuff
   myResult.setSomeData(slowWebService1.retriveSomeData(id));
   myResult.setSomeOtherData(slowWebService2.retriveSomeOtherData(id));
   myResult.setData(slowWebService3.retriveData(id));
   return myResult;
}

クライアントで:

Result result = webApplication.retriveData(10);
//use the result

私の提案は、呼び出しを複数の方法で分割することです。

 public SomeData retriveSomeData(Long id) {
    //do some stuff
    SomeData data = slowWebService1.retriveSomeData(id);
    //do more stuff
    return data;
 }

 public SomeOtherData retriveSomeOtherData(Long id) {
    //do some stuff
    SomeOtherData data = slowWebService2.retriveSomeOtherData(id);
    //do more stuff
    return data;
 }

 public Data retriveData(Long id) {
    //do some stuff
    Data data = slowWebService3.retriveData(id);
    //do more stuff
    return data;
 }

クライアントで:

//Call these methods in parallel, if you were using Swing, this could be done with
//SwingWorker (I have no idea how to it with Flash :)). 
//You can either wait for all methods to return or show partial results.
callInBackground(webApplication.retriveSomeData(10), useDataWhenDone);
callInBackground(webApplication.retriveSomeOtherData(10), useDataWhenDone);
callInBackground(webApplication.retriveData(10), useDataWhenDone);

これを行うことで、以前と同じように Web アプリケーションのみを呼び出しているため、セキュリティ上の問題は発生しません。

私はWebsphereに精通していないので、非同期Beanを使用することがこれよりも優れているかどうかはわかりませんが、手動でスレッドを開始することは避けるべきです.

于 2011-06-10T18:58:40.427 に答える