为什么OkHttp不重新使用它的连接? [英] Why OkHttp doesn't reuse its connections?

查看:29
本文介绍了为什么OkHttp不重新使用它的连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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.close()而不是response.body().string(),则SocketException不会发生,但netstat仍然显示大量的time_wait连接,基准性能越来越低。

我做错了什么?

PS:我尝试过使用ApacheHttpClient及其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);
    }
}

这意味着如果请求或响应中存在"Connection:Close"标头,okhttp将关闭连接

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

这篇关于为什么OkHttp不重新使用它的连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆