【问题标题】:HttpTimeout gracefully close connectionHttpTimeout 优雅地关闭连接
【发布时间】:2021-06-03 11:55:02
【问题描述】:

我正在使用 java Apache HttpClient 请求一个超时为 10 秒的资源 (B)。如果超时超过其他应用程序服务器上看到的损坏管道。

因为应用程序 B 的 Nginx 没有缓存响应。如何优雅地关闭连接,使其他应用服务器(B)不会遇到断管异常。

【问题讨论】:

  • 你在抓什么这么久? (即是否有不同的问题发生?)如果下载需要十秒钟或关闭,那么超时不应该更高吗?当然,一旦你开始从 B 拉回数据,你不应该以超时结束,数据包应该流回来......
  • 你是对的,但 SLA 并不完美,有时会超过超时,缓存层无法缓存,而应用服务器已计算响应但客户端已断开连接
  • 因此,除非该结果对另一个客户端有用 - 缓存是否值得?
  • Server A --> Server B (Heavy operation) .. Server B 是 tomcat + Nginx (caching) 如果从服务器 A 到 B 的调用超时。由于客户端中止连接,B 的 Tomcat 正在抛出损坏的管道异常。因此 nginx 无法缓存。所以,在这种情况下,tomcat 计算了一个有效的响应,但 nginx 没有缓存它。
  • 如果这发生在很大比例或您的电话中,您想知道原因/修复它(也许 10 秒在很多时候过于乐观)?但是,如果它不是很多,那么额外的 1% 命中可能是过度思考(优化不需要优化的东西)。

标签: java nginx tomcat caching apache-httpclient-4.x


【解决方案1】:

如果你使用的是足够新的 HttpClient,你不能做这样的事情吗(我刚刚发现了一个别人写的 sn-p ......但请看下面我添加的地方###)

   HttpClient client = HttpClient.newHttpClient();

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://localhost:8081/test/resource"))
        .header("Accept", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString("ping!"))
        .build();

    CompletableFuture<HttpResponse<String>> completableFuture =
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
    completableFuture
        .completeOnTimeout(DEFAULT_RESPONSE, 1, TimeUnit.SECONDS)  //  ### ADD THIS the HttpClientRequest actually continues but the future has timed out so the user of the client progresses  ??
        .thenApplyAsync(HttpResponse::headers)
        .thenAcceptAsync(System.out::println);
    HttpResponse<String> response = completableFuture.join();

【讨论】:

    猜你喜欢
    • 2015-06-25
    • 1970-01-01
    • 2012-10-29
    • 2019-06-27
    • 1970-01-01
    • 2011-08-07
    • 2012-04-05
    • 2010-11-23
    • 1970-01-01
    相关资源
    最近更新 更多