okhttp详解之连接池

本文,主要分析以下几个问题:

  1. 连接池ConnectionPool的定义及其详解。
  2. 连接connect复用详解。
  3. connet清理。
  4. 访问同一个地址的socket复用详解。
  5. .服务器重新定位, 包括IP地址重新定位、代理proxy重新定位。也就是如果当集群服务器存在多个代理,代理存在多个IP地址,那么访问一个IP地址失败的话,那么重新定位到另外一台服务器。
  6. okhttp的连接支持连接保持功能,也就是http1.1 和 http2.0所具有的功能,详解 BridgeInterceptor对requestHeader的处理。

了解以上okhttp的特点,需要通过StreamAlloction、ConnectionPool、RouteSelector、RealConnection等。

总体架构图如下:

源码详解:
okhttp最核心的架构就是拦截链路,其链路串起来了整个okhttp的网络请求,因此connectior的获取等入口在ConnectionInterceptor中。

1、connection 获取入口,ConnectionInterceptor,代码详解如下。

okhttp详解之连接池_第1张图片

2、创建请求流数据,HttpStream。
okhttp详解之连接池_第2张图片

3、获取connection。.

okhttp详解之连接池_第3张图片

okhttp详解之连接池_第4张图片

4、重定位服务器,因为集群服务器可能存在多台代理服务器,每个代理服务器可能存在多个ip地址,因此如果其中一个服务器的IP地址存在无法访问或者访问超时等情况,这里就可以进行重定位操作,依次尝试所有代理服务器中的所有IP地址,直到找到一个可用好用的服务器,详解以下代码。
okhttp详解之连接池_第5张图片

5、连接复用、Socket复用,代码如下:
okhttp详解之连接池_第6张图片

7、连接池ConnectionPool类的详解。

  • ConnectionPool 中的连接可以复用,如果请求的是同一个host,满足相关条件可以复用本connection不用重新建立服务器连接,因为和服务器建立连接会进行TCP的三次握手,并且TCP传送数据是一种懒传送模式,也就是最开始之后传送少量数据,然后才会慢慢增加传送量。这样三次握手和懒传送带来了网络延迟。
  • ConnectionPool 通过一个双向队列来维护connection,随着请求数量的增大,会带来一个问题,随着connection队列的增大内存的使用也随着加大 ,并且连接池中的连接可能还存在一些闲置不再使用的connection,那么这样就需要定时的对这个双向队列中的闲置连接进行清除,以达到节省资源。
  • ConnectionPool 中怎么来判断其中的一个connection是无用的呢?okhttp采用了JVM内存清理中的其中一种标记法,也就是只要connection引用一次则标记链表 List --> allocations(RealConnection中的对象)连接中增加一个streamAllocation,因为每次请求都会创建一个streamAllocation,因此链表中数据的个数就是请求的个数。当进行清理操作的时候,只要链表个数为0,则表示了本connection处于闲置状态,如果他达到了清理标准例如超过闲置时间等,在连接池中对其进行remove。
  • -清理工作是在一个子线程中循环处理的,循环条件是达到清理时间,可以详见后续打代码解析。
  • 清理过程有可能标记链表中的对象为null,因为本链表是弱引用,可能被GC掉。

ConnectionPool 代码详解如下:

ConnectionPool 代码详解如下:
okhttp详解之连接池_第7张图片

okhttp详解之连接池_第8张图片

okhttp详解之连接池_第9张图片

okhttp详解之连接池_第10张图片

okhttp详解之连接池_第11张图片

你可能感兴趣的:(okhttp,网络通讯,Android高级开发)