1

Spring RestTemplate を使用して、RestService への HTTP 呼び出しを行っています。RestTemplate のスプリング フレームワーク 3.2.8 バージョンを使用しています。私たちの会社にはSpring Frameworkバージョン3.2.8を使用している親POMがあるため、これをアップグレードすることはできません。

2台のマシンがあるとしましょう:

  • machineA: このマシンは、RestTemplate を HttpClient として使用するコードを実行しており、このマシンから、別のマシン (machineB) で実行されている RestService に HTTP 呼び出しを行います。以下のコードをマルチスレッド アプリケーションにラップして、クライアント コードで負荷テストとパフォーマンス テストを実行できるようにしました。
  • machineB: このマシンでは、RestService を実行しています。

現在、私が目にしている問題は、machineA で負荷とパフォーマンスのテストを実行するたびに発生することです。つまり、クライアント コードはマルチスレッドで呼び出されるため、machineB で実行されている RestService に対して多くの HTTPClient 呼び出しが非常に高速に行われます。

以下に示すように、常に多くの TIME_WAIT 接続がmachineA表示されます。

   298 ESTABLISHED
    14 LISTEN
     2 SYN_SENT
 10230 TIME_WAIT

  291 ESTABLISHED
   14 LISTEN
    1 SYN_SENT
17767 TIME_WAIT

    285 ESTABLISHED
   14 LISTEN
    1 SYN_SENT
24055 TIME_WAIT

ここに多くの TIME_WAIT 接続があるのは良い兆候ではないと思います。 問題文:-

  • この高いTIME_WAIT接続は、ここで machineA の単純な言語で何を意味するのでしょうか?
  • これが RestTemplate で起こっている理由はありますか、それとも私が RestTemplate を使用している方法ですか? RestTemplate の使用方法に何か問題がある場合、それを使用する正しい方法は何ですか?

RestTemplate を使用している間、keep-aliveヘッダーや何かを設定する必要がありますか? Connection:Closeここで何が起こっているのか混乱しているので、入力/提案は大歓迎です。

以下は、コードベースでRestTemplateを簡単な方法で使用する方法です(RestTemplateの使用方法の全体的なアイデアを説明するためだけです):

public class DataClient implements Client {

    private final RestTemplate restTemplate = new RestTemplate();
    private ExecutorService executor = Executors.newFixedThreadPool(10);

    // for synchronous call
    @Override
    public String getSyncData(DataKey key) {        
        String response = null;
        Future<String> handler = null;
        try {
            handler = getAsyncData(key);
            response = handler.get(100, TimeUnit.MILLISECONDS); // we have a 100 milliseconds timeout value set
        } catch (TimeoutException ex) {
            // log an exception
            handler.cancel(true);
        } catch (Exception ex) {
            // log an exception
        }

        return response;
    }

    // for asynchronous call
    @Override
    public Future<String> getAsyncData(DataKey key) {
        Future<String> future = null;

        try {
            Task task = new Task(key, restTemplate);
            future = executor.submit(task); 
        } catch (Exception ex) {
            // log an exception
        }

        return future;
    }
}

以下は私の単純なタスククラスです

class Task implements Callable<String> {

    private final RestTemplate restTemplate;
    private final DataKey key;

    public Task(DataKey key, RestTemplate restTemplate) {
        this.key = key;
        this.restTemplate = restTemplate;
    }

    public String call() throws Exception {
        ResponseEntity<String> response = null;

        String url = "some_url_created_by_using_key";

        // handling all try catch here
        response = restTemplate.exchange(url, HttpMethod.GET, null, String.class);

        return response.getBody();
    }
}
4

1 に答える 1