来自王老板的分享

OKHTTP系统架构模型

OKHTTP系统架构模型(王召)
OKHTTP系统架构模型(王召)

线程池

线程模型(王召)
线程模型(王召)

连接池(ConnectionPool)

连接池模型(王召)
连接池模型(王召)

思考

概述

  • 如何创建

  • 如何管理

  • 如何回收

要解决的问题

  • 连接池上限

  • 什么时候释放哪些连接

  • 有链接超时的情况

学习

协议

  • HTTP 1.0
  • HTTP 1.1
  • HTTP 2
  • SPDY 3.1
  • QUIK (Quick UDP Internet Connection)

创建

put新连接
  • 先检查空闲连接,将其清理
  • 放入新的连接
    1
    2
    3
    4
    5
    6
    7
    8
    void put(RealConnection connection) {
    assert (Thread.holdsLock(this));
    if (!cleanupRunning) {
    cleanupRunning = true;
    executor.execute(cleanupRunnable);
    }
    connections.add(connection);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private final Runnable cleanupRunnable = new Runnable() {
@Override
public void run() {
//循环执行清理操作
while (true) {
//返回清理执行等待的纳秒数
long waitNanos = cleanup(System.nanoTime());
if (waitNanos == -1) return;
if (waitNanos > 0) {
long waitMillis = waitNanos / 1000000L;
waitNanos -= (waitMillis * 1000000L);
synchronized (ConnectionPool.this) {
try {
ConnectionPool.this.wait(waitMillis, (int) waitNanos);
} catch (InterruptedException ignored) {
}
}
}
}
}
};
清理
如何找到闲置的连接
  • 通过pruneAndGetAllocationCount(connection, now)判断当前连接是不是在用
  • idleDurationNs纳秒数超过keepAliveDurationNs或者idleConnectionCount超过maxIdleConnections时,直接将当前连接移除
  • 上面情况不满足时,当idleConnectionCount > 0返回允许等待的时间差值
  • inUseConnectionCount > 0返回keepAlive的最大时间
  • 当前无连接不需要清理
如何判断连接是否在用
  • 主要检查ReferenceStreamAllocation是否为空,为空则说明有连接泄漏,程序有异常,不为空则返回Reference的列表size