使用RestTemplate时有很多TIME_WAIT连接?

时间:2015-06-05 06:26:02

标签: java spring tcp resttemplate time-wait

我使用Spring RestTemplate对我的RestService进行HTTP调用。我正在使用Spring框架3.2.8版本的RestTemplate。我不能升级这个,因为在我们公司我们有一个父POM,我们在其中使用Spring Framework版本3.2.8所以我需要坚持这一点。

假设我有两台机器:

  • machineA:这台机器正在运行我的代码,它使用RestTemplate作为我的HttpClient,我从这台机器向我的RestService发出HTTP调用,它运行在另一台机器(machineB)上。我已经将以下代码包装在多线程应用程序中,以便我可以对客户端代码进行负载和性能测试。
  • machineB:在这台机器上,我正在运行我的RestService。

现在我遇到的问题是每当我在machineA上运行负载和性能测试时 - 意思是,我的客户端代码将很快调用很多HTTPClient调用到在machineB上运行的RestService,因为客户端代码是在多线程中调用的方式。

我总是在machineA上看到很多TIME_WAIT连接,如下所示:

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

1 个答案:

答案 0 :(得分:0)

&#34; TIME_WAIT&#34;是TCP连接在关闭(FIN / FIN接收)后的可配置时间内保持的状态。通过这种方式,可能会延迟&#34;一个连接的数据包不能与后一个重用相同端口的连接混合使用。

在高流量测试中,拥有大量测试是正常的,但测试完成后它们应该会消失。