【发布时间】:2017-04-22 00:46:12
【问题描述】:
我正在使用 OkHttp 3.5.0 执行 http 基准测试。我正在向同一个 URL 发送数千个请求。
我希望 OkHttp 客户端使用 ConnectionPool 并一遍又一遍地重用其连接。但是如果我们查看netstat,我们会看到许多连接处于 TIME_WAIT 状态:
TCP 127.0.0.1:80 127.0.0.1:51752 TIME_WAIT
TCP 127.0.0.1:80 127.0.0.1:51753 TIME_WAIT
TCP 127.0.0.1:80 127.0.0.1:51754 TIME_WAIT
TCP 127.0.0.1:80 127.0.0.1:51755 TIME_WAIT
TCP 127.0.0.1:80 127.0.0.1:51756 TIME_WAIT
...
经过数千次请求后,我收到了SocketException: No buffer space available (maximum connections reached?)
代码执行请求(Kotlin):
val client = OkHttpClient.Builder()
.connectionPool(ConnectionPool(5, 1, TimeUnit.MINUTES))
.build()
val request = Request.Builder().url("http://192.168.0.50").build()
while (true) {
val response = client.newCall(request).execute()
response.close()
}
如果我使用response.body().string()而不是response.close(),那么SocketException不会发生,但netstat仍然显示大量TIME_WAIT连接,并且基准性能越来越低。
我做错了什么?
PS:我尝试过使用 Apache HttpClient 及其PoolingHttpClientConnectionManager,看起来效果很好。但我想弄清楚 OkHttp 有什么问题。
【问题讨论】:
-
你可以试试 response.body().string() 然后是 response.close()。您应该使用响应以便可以重用连接(假设 HTTP/1.1),然后您应该关闭响应。
-
threadCount是什么? -
@YuriSchimke 没有任何改变。其实
response.body().string()消费后执行close()。 -
@JesseWilson 从示例代码中删除了
threadCount。它只是一些核心。 -
@JesseWilson 好像我也有同样的问题。在基准测试期间性能会急剧下降。我不知道 JSnow 是否给你发了测试用例,但无论如何,这是我的:github.com/olegcherr/OkHttp-TimeWait-Test 另外,为了更方便,我创建了一个讨论:github.com/olegcherr/OkHttp-TimeWait-Test/issues/1
标签: http benchmarking okhttp