3

I have a multithreaded program whose thread number could be customized. The program is responsible for generating HTTP requests, sending the requests to a web service, receiving response and parsing the response to get some result value.

Since it takes almost 1 sec for each request to get the response, to make the program get as many responses as possible, multiple threads are started.

Following code is used to start multithreads:

    ...
    for (int i = 0; i < threadNum; i++) {
        threadArray[i] = new Thread(requestGeneratorArray[i]);
        threadArray[i].start();
    }

    for (int i = 0; i < threadNum; i++) {
        try {
            threadArray[i].join();
        } catch (InterruptedException e) {
            logger.error(e);
        }
    }

...

When the thread number is 50, and totally 10K requests are generated and sent, the program works well. When the thread number is still 50, and the total request number is 100K. The program was hanging when 95K+ requests were sent. No exception existed, and the program just hanging there.

And then I add a few JVM arguments like this: java -Xmx1024M -Xms512M -XX:MaxPermSize=256m ... With such arguments, 50 threads/ 100K request worked. However, 50 threads/ 1M requests was hanging again. I set the thread number to 20 and request number as 1M, it worked again.

I want to set the thread number to 50, since as tested with fewer requests number (10K), 50 threads makes the highest efficiency. The request number could be much larger as 10M, 100M, event 1B. In this cases, it would not be a good idea to increase the size of -Xmx -Xms or MaxPermSize. What should I do? What's the root cause of program hanging?

===========================================================

I used Executor Service instead of threads directly. But the problem occurred as well. I rechecked the code, and found there is a mistake : I instantiated a HttpClient object for each request. I changed the code to instantiated a HttpClient instance for each thread, and the program doesn't hang anymore.

I think the root cause of program hanging is that it set up too many HTTP connections to the web service, and used out all threads of the web service. That made the web service cannot answer to any new arrived requests. Is it correct?

4

3 に答える 3

1

Executor Serviceを使用するすべての提案に +1 。

また、Http クライアントを使用していると述べました。同時使用のために http クライアントを高速化する構成パラメーターはほとんどありません。

プログラムハングについて。大規模なガベージ コレクターの実行のデッドロックである可能性があります。jconsoleVisual VMなどのツールは、これら両方のシナリオのデバッグに役立つと思います。

于 2013-01-01T10:18:39.167 に答える
1

この情報だけから判断するのは困難ですが、ヒープ設定が結果に影響するという事実から、コンテンツの生成とコンテンツの解析 (保存) の間のスケジューリングがうまくいかないことが予想されます。

この種のアプリケーションでよくあるシナリオの 1 つは、コンテンツを生成するスレッドが、そのコンテンツを取得して保存するスレッドよりも高速に生成されることです。これにより、コンテンツをメモリ内に保持するために使用されるヒープ メモリの量が徐々に増加し、ある時点でスループットが急激に低下し始めます。

まず、VisualVM のようなヒープ ビューアーをアタッチして、この仮説を確認します。ヒープの使用量が徐々に増加し、高レベルで固定され始め、スループットが低下する場合、これが原因である可能性があります (メモリ内の内容が実際に生成された内容であることを確認することも できます)。

通常、ボトルネックは、コンテンツの保存に使用される永続レイヤーの IO です。コードの実行内容によっては、解析コード (または他の場所) で CPU ボトルネックが発生 する可能性がありますが、これは一般的にまれです。

この状況に対する最も一般的な解決策は、バインドされたキューを使用して、解析 (格納) プロセスが追いつくまで生成プロセスを待機させることです。この SO の回答をご覧ください: ThreadPoolExecutor の submit() メソッドが飽和している場合にブロックする方法は? . スレッド プールについて学ぶ必要がありますが、これは生のスレッドよりも大幅に改善されており、この種の問題に対処する最もクリーンな方法です。

于 2013-01-01T08:46:54.963 に答える
1

スレッドがハングする場所がわからないので、プロファイラーまたは ThreadMXBeans を使用して、スレッドの定期的なスタック トレースを取得し、ある種のスレッド モニタリングを検討しましたか? 他のポスターの一部が言及しているように、スケーラビリティの問題がある場合は、gc.log にも目を向ける必要があります。そして、あなたのメモリフットプリントを見てください。しかし、これはここでは問題ではないかもしれません。完全な gc でさえ最終的には終了するはずですが、あなたのプログラムはそうではありません。

于 2013-01-03T13:56:22.830 に答える