【问题标题】:webclient less than 3 seconds response or 45 secondswebclient 少于 3 秒响应或 45 秒
【发布时间】:2020-03-17 11:42:18
【问题描述】:

我有一个非常基本的 spring boot 2.2.4 应用程序,它使用带有阻塞调用的 webclient 查询下游系统。我没有对网络客户端进行任何配置(设置超时等),只是“开箱即用”地使用它。

我发现 webclient 调用的响应时间要么低于 3 秒,要么正好 45 秒,我觉得很奇怪。为什么如果响应很慢,它总是 45 秒?

我能找到的关于 45 秒的唯一参考来自 Reactor Netty 文档:

4.6。连接池

默认情况下,TCP 客户端使用“固定”连接池,最大通道数为 500,获取超时时间为 45s。这意味着如果有人尝试获取一个通道但池中没有一个通道,则该实现会创建一个新通道。当达到池中通道的最大数量时,将延迟新尝试获取通道,直到通道再次返回池中。该实现对池中的通道使​​用 FIFO 顺序。默认情况下,池中的通道没有指定空闲时间。

对于为什么我的慢速网络客户端调用总是需要 45 秒才能完成,有人有什么建议吗?

【问题讨论】:

  • 一个调用需要45s,是成功还是失败?如果它失败了,那就是错误?
  • 另外,请尝试使用 IP 地址而不是域名进行连接。这将消除或表明与 DNS 相关的可能问题
  • @Matt,它成功了,永远不会失败。

标签: java spring-boot reactor-netty spring-webclient


【解决方案1】:

发生这种情况是因为固定池大小为 500。如果所有这些连接(通道)当前都被现有请求使用,则新的连接请求将排队等待 500 个连接中的一个空闲。如果 WebClient 无法在 45 秒内为新请求获取连接(因为所有 500 个通道仍被现有请求阻塞),它将失败并出现 AcquireTimeout 异常。我假设在 3 秒之前完成的是成功的,而 45 秒的则是失败的。根据应用程序的吞吐量,您可以相应地调整池大小。

【讨论】:

  • 45 秒的也成功了 - 没有失败。
【解决方案2】:

过去,当我看到成功连接时出现这样的延迟时,原因如下:

  1. 您尝试使用域名连接,因此客户端首先调用 DNS 获取地址;
  2. DNS 返回 IPv4 和 IPv6 的地址记录
  3. 客户端先尝试 IPv6,但网络上的 IPv6 配置不正确,在 IPv6 连接超时后失败,超时时间可能在 45s 范围内。
  4. 客户端然后尝试 IPv4,成功。

这是否发生在您身上取决于您的操作系统+版本、Java 版本和网络配置。

尝试使用 IPv4 IP 地址连接,例如 http://192.168.10.1/the/rest。如果它总是很快,那么您可能遇到了上述问题。不幸的是,您通常无法通过 HTTPS 以这种方式连接,但根据您的操作系统,您可以尝试在 /etc/hosts 中填充正确的 v4 地址。

在这里查看更多信息:https://serverfault.com/questions/548777/how-to-prevent-delays-associated-with-ipv6-aaaa-records

【讨论】:

    【解决方案3】:

    我认为这与这个网络问题有关:

    https://github.com/reactor/reactor-netty/issues/1012

    我现在先看看。

    感谢大家的回复!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 2018-05-10
      • 2011-06-13
      • 1970-01-01
      • 2022-06-27
      相关资源
      最近更新 更多