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();
}
}