java - 使用 RestTemplate 时有很多 TIME_WAIT 连接?

标签 java spring tcp resttemplate time-wait

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

假设我有两台机器:

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

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

我总是在 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 header 或 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();
    }
}

最佳答案

“TIME_WAIT”是 TCP 连接在关闭(FIN/FIN 接收)后一段可配置的时间内保持的状态。这样,一个连接的可能“延迟”数据包就不能与重用同一端口的后一个连接混合。

在高流量测试中,有很多是正常的,但在测试完成几分钟后它们应该会消失。

关于java - 使用 RestTemplate 时有很多 TIME_WAIT 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30659735/

相关文章:

java - WebClient 在 JUnit 中导致 "java.lang.IllegalStateException: executor not accepting a task"

java - 重新启动 TCP 服务器

java - 如何清空输入流?

java - 为什么 BufferedReader 读取的行数多于 wc 命令检测到的大文件行数?

java - ClassPathXmlApplicationContext 读取 JAR 外部的文件

java - 每月 25 日触发的 Cron 表达式

java - com.jcraft.jsch.ChannelSftp.get(String src,String dst) 会覆盖现有文件吗?

java - 在 android 上使用 jackson-dataformat-xml

tcp - 从 * char eth/ip/tcp 打包程序表示中获取 TCP 选项(超出 tcphdr->doff)

java - 如何在 Windows 和 Java 11 上调试 "Software caused connection abort: recv failed"?