【发布时间】:2016-09-15 09:53:09
【问题描述】:
我正在使用RestTemplate 来执行并发 HTTP 请求。一段时间后,我开始得到 p>
java.net.SocketException:没有可用的缓冲区空间(最大 已建立连接?)
- 我知道这与处于 TIME_WAIT 状态的套接字有关。
- 我已尝试安装 Windows 7 修复程序,大多数来源都鼓励这样做。
-
我将
RestTemplate配置为使用HttpClient如下:val httpClient = HttpClientBuilder.create() .setMaxConnPerRoute(properties.concurrencyLimit) .setMaxConnTotal(properties.concurrencyLimit) .build() return RestTemplate(HttpComponentsClientHttpRequestFactory(httpClient)) 我已尝试使用十亿个其他
HttpClient配置- 我尝试了 20-100 之间不同数量的并发请求
就在我要按下发布您的问题按钮之前,我的同事找到了一个对我来说没有任何意义的解决方案:
val httpClient = HttpClientBuilder.create()
.setMaxConnPerRoute(properties.concurrencyLimit * 2)
.setMaxConnTotal(properties.concurrencyLimit * 2)
.build()
return RestTemplate(HttpComponentsClientHttpRequestFactory(httpClient))
基本上,当我将连接池设置为线程数的两倍时,整个事情就像一个魅力。
为什么?为什么第一个配置不起作用而第二个配置起作用?
所有依赖都由 Spring Boot 1.4.0.RELEASE 父 pom 管理。
【问题讨论】:
-
如果您使用异步连接器或异步 servlet,那么在您休息时,线程可以为其他请求提供服务,这意味着当 nex 请求到来并尝试获取连接以进行 http 调用时,将不会剩下的连接
-
这是一个批处理作业。它所做的只是:它到达两个端点并组合结果,最后打印一个报告。
-
在您的批次中,您是否一个一个地执行 http 请求?然后在http 1.1中,如果当前http(在tcp下)连接忙于进行http请求,其他reuest将采用新连接,直到http 2.0才有多路复用。因此,您的批处理将使用多个 http 连接,并且它们可以比您的线程处理批处理更快地耗尽。
-
这就是我想使用连接池的原因。我目前最好的理论是,当交替访问 2 个服务并且到每个服务的连接不是 50/50 分布时,一些连接将被“丢弃”。当足够多的连接被丢弃并且它们的套接字处于 TIME_WAIT 时,池无法建立任何新的连接。你怎么看?
标签: java spring-boot apache-httpclient-4.x resttemplate socketexception