gpt4 book ai didi

http - 为什么 OkHttp 不重用它的连接?

转载 作者:可可西里 更新时间:2023-11-01 15:21:53 28 4
gpt4 key购买 nike

我正在使用 OkHttp 3.5.0 执行 http 基准测试。我向同一个 URL 发送了数千个请求。

我希望 OkHttp-client 使用 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:没有可用的缓冲区空间(达到最大连接数?)

执行请求的代码 (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 有什么问题。

最佳答案

我的版本是3.13.0,离3.5.0不远了,我也遇到了TIME_WAIT的问题。

深入研究源代码后,我在 CallServerInterceptor.java 第 142 行找到:

if ("close".equalsIgnoreCase(response.request().header("Connection"))
|| "close".equalsIgnoreCase(response.header("Connection"))) {
streamAllocation.noNewStreams();
}

在 StreamAllocation.java 第 367 行:

public void noNewStreams() {
Socket socket;
Connection releasedConnection;
synchronized (connectionPool) {
releasedConnection = connection;
socket = deallocate(true, false, false); // close connection!
if (connection != null) releasedConnection = null;
}
closeQuietly(socket);
if (releasedConnection != null) {
eventListener.connectionReleased(call, releasedConnection);
}
}

这意味着如果请求或响应中存在“连接:关闭” header ,okhttp 将关闭连接

虽然问题提交已经很久了,但我希望这个答案能帮助遇到这个问题的人,祝你好运。

关于http - 为什么 OkHttp 不重用它的连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41011287/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com