OkHttp3 内部工作原理时序图

170 阅读4分钟

OkHttp3 内部工作原理时序图

本文档深入剖析OkHttp3框架的内部工作机制,展示其核心组件的交互流程。

1. OkHttpClient 构建流程

sequenceDiagram
    participant Client as 开发者代码
    participant Builder as OkHttpClient.Builder
    participant Dispatcher as Dispatcher
    participant ConnectionPool as ConnectionPool
    participant OkHttpClient as OkHttpClient

    Client->>Builder: new OkHttpClient.Builder()
    activate Builder

    Note over Builder: 配置网络参数
    Client->>Builder: connectTimeout(duration)
    Builder->>Builder: 设置连接超时
    Client->>Builder: readTimeout(duration)
    Builder->>Builder: 设置读超时
    Client->>Builder: writeTimeout(duration)
    Builder->>Builder: 设置写超时

    Note over Builder: 配置拦截器
    Client->>Builder: addInterceptor(interceptor)
    Builder->>Builder: interceptors.add()
    Client->>Builder: addNetworkInterceptor(interceptor)
    Builder->>Builder: networkInterceptors.add()

    Note over Builder: 配置连接池
    Client->>Builder: connectionPool(pool)
    alt 未指定连接池
        Builder->>ConnectionPool: new ConnectionPool()
        activate ConnectionPool
        ConnectionPool->>ConnectionPool: 最大空闲连接: 5
        ConnectionPool->>ConnectionPool: 保活时间: 5分钟
        ConnectionPool-->>Builder: 返回默认连接池
        deactivate ConnectionPool
    end

    Note over Builder: 配置调度器
    Client->>Builder: dispatcher(dispatcher)
    alt 未指定调度器
        Builder->>Dispatcher: new Dispatcher()
        activate Dispatcher
        Dispatcher->>Dispatcher: 最大并发请求: 64
        Dispatcher->>Dispatcher: 单Host最大请求: 5
        Dispatcher->>Dispatcher: 创建线程池ExecutorService
        Dispatcher-->>Builder: 返回调度器
        deactivate Dispatcher
    end

    Client->>Builder: build()
    Builder->>OkHttpClient: new OkHttpClient(builder)
    activate OkHttpClient
    OkHttpClient->>OkHttpClient: 复制所有配置
    OkHttpClient-->>Builder: 返回OkHttpClient实例
    deactivate OkHttpClient

    Builder-->>Client: 返回配置好的client
    deactivate Builder

2. 同步请求执行流程

sequenceDiagram
    participant Client as 开发者代码
    participant OkHttpClient as OkHttpClient
    participant RealCall as RealCall
    participant Dispatcher as Dispatcher
    participant Chain as RealInterceptorChain
    participant Interceptors as 拦截器链
    participant Network as 网络服务器

    Client->>OkHttpClient: newCall(request)
    activate OkHttpClient
    OkHttpClient->>RealCall: new RealCall(client, request)
    activate RealCall
    RealCall->>RealCall: 初始化Call对象
    RealCall-->>OkHttpClient: 返回Call实例
    deactivate RealCall
    OkHttpClient-->>Client: 返回Call
    deactivate OkHttpClient

    Note over Client,RealCall: 执行同步请求
    Client->>RealCall: execute()
    activate RealCall

    RealCall->>RealCall: 检查是否已执行
    alt 已执行
        RealCall-->>Client: throw IllegalStateException
    end

    RealCall->>RealCall: executed = true
    RealCall->>Dispatcher: executed(call)
    activate Dispatcher
    Dispatcher->>Dispatcher: runningSyncCalls.add(call)
    Dispatcher-->>RealCall: 记录同步调用
    deactivate Dispatcher

    RealCall->>RealCall: getResponseWithInterceptorChain()
    activate RealCall

    RealCall->>Chain: new RealInterceptorChain()
    activate Chain
    Chain->>Chain: 构建拦截器链
    Chain-->>RealCall: 返回Chain
    deactivate Chain

    RealCall->>Chain: proceed(request)
    activate Chain
    Chain->>Interceptors: 执行拦截器链
    activate Interceptors
    Note over Interceptors: 依次执行所有拦截器
    Interceptors->>Network: 发送网络请求
    activate Network
    Network-->>Interceptors: 返回响应
    deactivate Network
    Interceptors-->>Chain: 返回Response
    deactivate Interceptors
    Chain-->>RealCall: 返回Response
    deactivate Chain

    RealCall-->>RealCall: 返回Response
    deactivate RealCall

    RealCall->>Dispatcher: finished(call)
    activate Dispatcher
    Dispatcher->>Dispatcher: runningSyncCalls.remove(call)
    Dispatcher-->>RealCall: 完成
    deactivate Dispatcher

    RealCall-->>Client: 返回Response
    deactivate RealCall

3. 异步请求执行流程

sequenceDiagram
    participant Client as 开发者代码
    participant RealCall as RealCall
    participant Dispatcher as Dispatcher
    participant ExecutorService as 线程池
    participant AsyncCall as AsyncCall
    participant Chain as 拦截器链
    participant Callback as Callback

    Client->>RealCall: enqueue(callback)
    activate RealCall

    RealCall->>AsyncCall: new AsyncCall(callback)
    activate AsyncCall
    AsyncCall->>AsyncCall: 封装回调
    AsyncCall-->>RealCall: 返回AsyncCall
    deactivate AsyncCall

    RealCall->>Dispatcher: enqueue(asyncCall)
    activate Dispatcher

    Dispatcher->>Dispatcher: 检查并发限制

    alt 可以立即执行
        Note over Dispatcher: runningAsyncCalls < 64<br/>且单Host请求 < 5
        Dispatcher->>Dispatcher: runningAsyncCalls.add(call)
        Dispatcher->>ExecutorService: execute(asyncCall)
        activate ExecutorService
        ExecutorService-->>Dispatcher: 提交成功
        deactivate ExecutorService
    else 需要等待
        Dispatcher->>Dispatcher: readyAsyncCalls.add(call)
        Note over Dispatcher: 加入等待队列
    end

    Dispatcher-->>RealCall: 入队成功
    deactivate Dispatcher
    RealCall-->>Client: 立即返回
    deactivate RealCall

    Note over ExecutorService,AsyncCall: 在线程池中异步执行
    ExecutorService->>AsyncCall: run()
    activate AsyncCall

    AsyncCall->>Chain: getResponseWithInterceptorChain()
    activate Chain

    Note over Chain: 执行拦截器链
    Chain->>Chain: 依次执行所有拦截器
    Chain->>Chain: 发送网络请求
    Chain->>Chain: 接收响应
    Chain-->>AsyncCall: 返回Response或抛出异常
    deactivate Chain

    alt 请求成功
        AsyncCall->>Callback: onResponse(call, response)
        activate Callback
        Callback-->>AsyncCall: 处理成功响应
        deactivate Callback
    else 请求失败
        AsyncCall->>Callback: onFailure(call, exception)
        activate Callback
        Callback-->>AsyncCall: 处理失败
        deactivate Callback
    end

    AsyncCall->>Dispatcher: finished(asyncCall)
    activate Dispatcher
    Dispatcher->>Dispatcher: runningAsyncCalls.remove(call)
    Dispatcher->>Dispatcher: promoteAndExecute()

    Note over Dispatcher: 提升等待队列中的请求
    Dispatcher->>Dispatcher: 遍历readyAsyncCalls
    Dispatcher->>Dispatcher: 移动符合条件的到runningAsyncCalls
    Dispatcher->>ExecutorService: 执行新的AsyncCall
    activate ExecutorService
    ExecutorService-->>Dispatcher: 提交成功
    deactivate ExecutorService

    Dispatcher-->>AsyncCall: 完成
    deactivate Dispatcher
    deactivate AsyncCall

4. 拦截器链执行流程

sequenceDiagram
    participant RealCall as RealCall
    participant RetryInterceptor as 1.RetryAndFollowUp
    participant BridgeInterceptor as 2.Bridge
    participant CacheInterceptor as 3.Cache
    participant ConnectInterceptor as 4.Connect
    participant CallServerInterceptor as 5.CallServer
    participant Network as 网络

    RealCall->>RetryInterceptor: chain.proceed(request)
    activate RetryInterceptor
    Note over RetryInterceptor: 重试和重定向拦截器
    RetryInterceptor->>RetryInterceptor: 创建StreamAllocation

    RetryInterceptor->>BridgeInterceptor: chain.proceed(request)
    activate BridgeInterceptor
    Note over BridgeInterceptor: 桥接拦截器-添加Headers
    BridgeInterceptor->>BridgeInterceptor: 添加Content-Type/Host<br/>Connection/Accept-Encoding<br/>Cookie/User-Agent

    BridgeInterceptor->>CacheInterceptor: chain.proceed(request)
    activate CacheInterceptor
    Note over CacheInterceptor: 缓存拦截器
    CacheInterceptor->>CacheInterceptor: 读取缓存

    alt 使用缓存
        Note over CacheInterceptor: 缓存有效,直接返回
        CacheInterceptor-->>BridgeInterceptor: 返回缓存Response
    else 需要网络请求
        CacheInterceptor->>ConnectInterceptor: chain.proceed(request)
        activate ConnectInterceptor
        Note over ConnectInterceptor: 连接拦截器
        ConnectInterceptor->>ConnectInterceptor: 获取/创建连接
        ConnectInterceptor->>ConnectInterceptor: 建立TCP连接
        ConnectInterceptor->>ConnectInterceptor: TLS握手(HTTPS)

        ConnectInterceptor->>CallServerInterceptor: chain.proceed(request)
        activate CallServerInterceptor
        Note over CallServerInterceptor: 请求服务器拦截器

        CallServerInterceptor->>Network: 写入请求
        activate Network
        Network->>Network: 处理请求
        Network-->>CallServerInterceptor: 返回响应
        deactivate Network

        CallServerInterceptor-->>ConnectInterceptor: Response
        deactivate CallServerInterceptor

        ConnectInterceptor-->>CacheInterceptor: Response
        deactivate ConnectInterceptor

        CacheInterceptor->>CacheInterceptor: 写入缓存(如果可缓存)
        CacheInterceptor-->>BridgeInterceptor: Response
    end
    deactivate CacheInterceptor

    BridgeInterceptor->>BridgeInterceptor: 解压gzip/保存Cookie
    BridgeInterceptor-->>RetryInterceptor: Response
    deactivate BridgeInterceptor

    alt 需要重试或重定向
        Note over RetryInterceptor: 3xx/408/503状态码
        RetryInterceptor->>RetryInterceptor: 构建新请求
        RetryInterceptor->>BridgeInterceptor: 重新执行拦截器链
        Note over RetryInterceptor: 最多重试20次
    else 成功响应
        RetryInterceptor-->>RealCall: 返回最终Response
    end
    deactivate RetryInterceptor

5. 连接池管理机制

sequenceDiagram
    participant Call as RealCall
    participant Interceptor as ConnectInterceptor
    participant Finder as ExchangeFinder
    participant Pool as ConnectionPool
    participant Connection as RealConnection
    participant Socket as Socket

    Note over Call,Pool: 阶段1:从连接池获取连接
    Call->>Interceptor: intercept(chain)
    activate Interceptor
    Interceptor->>Finder: find()
    activate Finder

    Finder->>Pool: get(address, call)
    activate Pool
    Pool->>Pool: 遍历connections查找匹配
    Pool->>Connection: isEligible(address)
    activate Connection
    Connection->>Connection: 检查Host/端口/协议
    Connection-->>Pool: 匹配结果
    deactivate Connection

    alt 找到匹配的连接
        Pool->>Connection: acquire(call)
        activate Connection
        Connection->>Connection: calls.add(call)
        Connection-->>Pool: 分配成功
        deactivate Connection
        Pool-->>Finder: 返回可用连接
        Finder-->>Interceptor: 返回连接
        Interceptor-->>Call: 使用已有连接
        Note over Call: 复用连接,流程结束
    else 未找到可用连接
        Pool-->>Finder: 返回null
        Note over Finder,Socket: 阶段2:创建新连接
        Finder->>Connection: new RealConnection()
        activate Connection
        Connection->>Socket: 建立TCP连接
        activate Socket
        Socket->>Socket: connect(address, timeout)
        Socket-->>Connection: 连接建立
        deactivate Socket

        Connection->>Connection: TLS握手(如果HTTPS)
        Connection-->>Finder: 返回新连接
        deactivate Connection

        Finder->>Pool: put(connection)
        Pool->>Pool: connections.add()
        Pool->>Pool: 触发清理任务
        Pool-->>Finder: 加入成功
        Finder-->>Interceptor: 返回新连接
        Interceptor-->>Call: 使用新连接
        Note over Call: 新连接已就绪
    end
    deactivate Pool
    deactivate Finder
    deactivate Interceptor

    Note over Pool: 阶段3:后台清理任务
    Pool->>Pool: cleanup()定期执行
    activate Pool
    Pool->>Pool: 遍历所有连接
    Pool->>Connection: 检查空闲时间和数量
    activate Connection

    Connection->>Connection: 判断清理条件
    Note over Connection: 空闲>5分钟 或 超过最大数5
    Connection-->>Pool: 返回是否需要清理
    deactivate Connection

    Pool->>Pool: 移除过期连接
    Pool->>Connection: close()
    activate Connection
    Connection->>Connection: 关闭Socket
    deactivate Connection
    Pool->>Pool: 计算下次清理时间
    deactivate Pool

6. HTTP/2 多路复用机制

sequenceDiagram
    participant Call1 as Request1
    participant Call2 as Request2
    participant Connection as RealConnection
    participant Http2 as Http2Connection
    participant Stream1 as Http2Stream(id=1)
    participant Stream2 as Http2Stream(id=3)
    participant Socket as TCP Socket
    participant Server as 服务器

    Note over Call1,Connection: 第一个请求建立HTTP/2连接
    Call1->>Connection: connect()
    activate Connection
    Connection->>Socket: 建立TCP连接
    activate Socket
    Socket-->>Connection: 连接成功
    Connection->>Http2: new Http2Connection()
    activate Http2
    Http2->>Socket: 发送连接前言(Preface)
    Socket->>Server: PRI * HTTP/2.0
    activate Server
    Server-->>Socket: 返回SETTINGS帧
    Socket->>Http2: 接收SETTINGS帧
    Http2->>Http2: 初始化连接参数
    Http2-->>Connection: HTTP/2连接就绪
    deactivate Http2
    deactivate Socket
    deactivate Connection

    Note over Call1,Stream1: 第一个请求使用Stream1
    Call1->>Http2: newStream()
    activate Http2
    Http2->>Stream1: new Http2Stream(streamId=1)
    activate Stream1
    Stream1-->>Http2: 返回Stream1
    Http2-->>Call1: 返回Stream1
    deactivate Http2

    Call1->>Stream1: writeRequestHeaders()
    Stream1->>Socket: 发送HEADERS帧(streamId=1)
    activate Socket
    Socket->>Server: HEADERS帧
    Stream1->>Socket: 发送DATA帧(streamId=1)
    Socket->>Server: DATA帧
    deactivate Socket

    Note over Call2,Stream2: 第二个请求复用同一连接
    Call2->>Connection: 获取已有连接
    activate Connection
    Connection-->>Call2: 返回相同的Http2Connection
    deactivate Connection

    Call2->>Http2: newStream()
    activate Http2
    Http2->>Stream2: new Http2Stream(streamId=3)
    activate Stream2
    Stream2-->>Http2: 返回Stream2
    Http2-->>Call2: 返回Stream2
    deactivate Http2

    Note over Stream1,Stream2: 两个流在同一TCP连接上并发

    Call2->>Stream2: writeRequestHeaders()
    Stream2->>Socket: 发送HEADERS帧(streamId=3)
    activate Socket
    Socket->>Server: HEADERS帧
    Stream2->>Socket: 发送DATA帧(streamId=3)
    Socket->>Server: DATA帧

    Note over Server: 服务器并发处理两个请求

    Server->>Socket: HEADERS帧(streamId=1)
    Socket->>Stream1: 接收HEADERS帧
    Stream1->>Call1: onResponse()
    activate Call1

    Server->>Socket: DATA帧(streamId=3)
    Socket->>Stream2: 接收DATA帧
    Stream2->>Call2: onResponse()
    activate Call2

    Server->>Socket: DATA帧(streamId=1)
    Socket->>Stream1: 接收DATA帧
    Stream1-->>Call1: 响应体
    deactivate Call1

    Server->>Socket: DATA帧(streamId=3, END_STREAM)
    Socket->>Stream2: 接收DATA帧
    Stream2-->>Call2: 响应体
    deactivate Socket
    deactivate Server
    deactivate Call2

    Stream1->>Stream1: 流关闭
    deactivate Stream1
    Stream2->>Stream2: 流关闭
    deactivate Stream2

7. 缓存机制详解

sequenceDiagram
    participant Call as RealCall
    participant CacheInterceptor as CacheInterceptor
    participant Cache as Cache
    participant DiskLruCache as DiskLruCache
    participant CacheStrategy as CacheStrategy
    participant Network as 网络

    Call->>CacheInterceptor: intercept(chain)
    activate CacheInterceptor

    Note over CacheInterceptor,Cache: 阶段1:读取缓存
    CacheInterceptor->>Cache: get(request)
    activate Cache
    Cache->>Cache: 计算key = hash(url)
    Cache->>DiskLruCache: get(key)
    activate DiskLruCache
    DiskLruCache->>DiskLruCache: 读取缓存文件
    DiskLruCache-->>Cache: 返回缓存条目或null
    deactivate DiskLruCache
    Cache->>Cache: 解析响应头和响应体
    Cache-->>CacheInterceptor: 返回Response或null
    deactivate Cache

    Note over CacheInterceptor,CacheStrategy: 阶段2:确定缓存策略
    CacheInterceptor->>CacheStrategy: get(request, cacheResponse)
    activate CacheStrategy
    CacheStrategy->>CacheStrategy: 分析Cache-Control
    CacheStrategy->>CacheStrategy: 检查max-age/Expires
    CacheStrategy->>CacheStrategy: 检查ETag/Last-Modified
    CacheStrategy-->>CacheInterceptor: 返回策略(networkRequest, cacheResponse)
    deactivate CacheStrategy

    Note over CacheInterceptor: 阶段3:执行策略

    alt 策略1:仅使用缓存
        Note over CacheInterceptor: networkRequest==null
        CacheInterceptor-->>Call: 返回缓存Response
    else 策略2:发送网络请求
        CacheInterceptor->>Network: chain.proceed(request)
        activate Network
        Network-->>CacheInterceptor: 返回networkResponse
        deactivate Network

        alt 响应304 Not Modified
            CacheInterceptor->>CacheInterceptor: 合并缓存和网络响应
            CacheInterceptor->>Cache: update(cacheResponse)
            activate Cache
            Cache->>DiskLruCache: 更新响应头
            activate DiskLruCache
            DiskLruCache-->>Cache: 更新成功
            deactivate DiskLruCache
            Cache-->>CacheInterceptor: 完成
            deactivate Cache
            CacheInterceptor-->>Call: 返回更新后的缓存
        else 响应200 OK
            CacheInterceptor->>CacheInterceptor: 检查是否可缓存
            CacheInterceptor->>Cache: put(response)
            activate Cache
            Cache->>Cache: 验证Cache-Control
            Cache->>Cache: 验证响应码
            Cache->>DiskLruCache: put(key, response)
            activate DiskLruCache
            DiskLruCache->>DiskLruCache: 写入响应头
            DiskLruCache->>DiskLruCache: 写入响应体
            DiskLruCache-->>Cache: 写入成功
            deactivate DiskLruCache
            Cache-->>CacheInterceptor: 缓存成功
            deactivate Cache
            CacheInterceptor-->>Call: 返回网络Response
        end
    end

    deactivate CacheInterceptor

8. WebSocket 连接机制

sequenceDiagram
    participant Client as 开发者代码
    participant OkHttpClient as OkHttpClient
    participant RealWebSocket as RealWebSocket
    participant WebSocketWriter as WebSocketWriter
    participant WebSocketReader as WebSocketReader
    participant RealCall as RealCall
    participant Server as WebSocket服务器

    Client->>OkHttpClient: newWebSocket(request, listener)
    activate OkHttpClient

    OkHttpClient->>RealWebSocket: new RealWebSocket()
    activate RealWebSocket
    RealWebSocket->>RealWebSocket: 初始化WebSocket
    RealWebSocket-->>OkHttpClient: 返回WebSocket实例
    OkHttpClient-->>Client: 返回WebSocket
    deactivate OkHttpClient

    Note over RealWebSocket: 发起WebSocket握手
    RealWebSocket->>RealCall: 创建HTTP升级请求
    activate RealCall
    RealCall->>RealCall: 添加升级Headers<br/>Upgrade: websocket<br/>Connection: Upgrade<br/>Sec-WebSocket-Key<br/>Sec-WebSocket-Version: 13

    RealCall->>Server: 发送HTTP请求
    activate Server
    Server->>Server: 验证WebSocket握手
    Server-->>RealCall: 101 Switching Protocols
    deactivate Server

    RealCall->>RealCall: 验证响应<br/>Sec-WebSocket-Accept
    RealCall-->>RealWebSocket: 握手成功
    deactivate RealCall

    Note over RealWebSocket: 初始化读写
    RealWebSocket->>WebSocketWriter: initWriter(streams)
    activate WebSocketWriter
    WebSocketWriter->>WebSocketWriter: 初始化输出流
    WebSocketWriter-->>RealWebSocket: Writer就绪
    deactivate WebSocketWriter

    RealWebSocket->>WebSocketReader: initReader(streams)
    activate WebSocketReader
    WebSocketReader->>WebSocketReader: 初始化输入流
    WebSocketReader-->>RealWebSocket: Reader就绪
    deactivate WebSocketReader

    RealWebSocket->>Client: onOpen(webSocket, response)
    activate Client
    Client-->>RealWebSocket: 连接已打开
    deactivate Client

    Note over Client,Server: 双向通信阶段

    Client->>RealWebSocket: send(text)
    activate RealWebSocket
    RealWebSocket->>WebSocketWriter: writeMessageFrame(TEXT, text)
    activate WebSocketWriter
    WebSocketWriter->>WebSocketWriter: 添加掩码(Mask)
    WebSocketWriter->>WebSocketWriter: 构建WebSocket帧
    WebSocketWriter->>Server: 发送TEXT帧
    activate Server
    WebSocketWriter-->>RealWebSocket: 发送成功
    deactivate WebSocketWriter
    RealWebSocket-->>Client: 返回true
    deactivate RealWebSocket

    Server->>WebSocketReader: 接收TEXT帧
    activate WebSocketReader
    WebSocketReader->>WebSocketReader: 读取帧头
    WebSocketReader->>WebSocketReader: 读取Payload
    WebSocketReader->>RealWebSocket: processFrame(TEXT, payload)
    deactivate WebSocketReader
    activate RealWebSocket
    RealWebSocket->>Client: onMessage(text)
    activate Client
    Client-->>RealWebSocket: 处理消息
    deactivate Client
    deactivate RealWebSocket

    Note over RealWebSocket,Server: Ping/Pong心跳

    RealWebSocket->>WebSocketWriter: writePing()
    activate WebSocketWriter
    WebSocketWriter->>Server: 发送PING帧
    Server-->>WebSocketWriter: 返回PONG帧
    deactivate Server
    deactivate WebSocketWriter

    WebSocketReader->>RealWebSocket: processPong()
    activate WebSocketReader
    activate RealWebSocket
    RealWebSocket->>RealWebSocket: 更新最后Pong时间
    deactivate RealWebSocket
    deactivate WebSocketReader

    Note over Client,Server: 关闭连接

    Client->>RealWebSocket: close(code, reason)
    activate RealWebSocket
    RealWebSocket->>WebSocketWriter: writeClose(code, reason)
    activate WebSocketWriter
    WebSocketWriter->>Server: 发送CLOSE帧
    activate Server
    WebSocketWriter-->>RealWebSocket: 发送成功
    deactivate WebSocketWriter

    Server->>WebSocketReader: 接收CLOSE帧
    activate WebSocketReader
    WebSocketReader->>RealWebSocket: processClose()
    deactivate WebSocketReader
    RealWebSocket->>Client: onClosing(code, reason)
    activate Client
    Client-->>RealWebSocket: 确认关闭
    deactivate Client

    Server-->>RealWebSocket: 关闭连接
    deactivate Server

    RealWebSocket->>Client: onClosed(code, reason)
    activate Client
    Client-->>RealWebSocket: 连接已关闭
    deactivate Client
    deactivate RealWebSocket

9. 完整请求生命周期流程图

flowchart TD
    Start([创建Request]) --> NewCall[OkHttpClient.newCall]
    NewCall --> ChooseSync{同步还是异步?}

    ChooseSync -->|execute| SyncExec[同步执行]
    ChooseSync -->|enqueue| AsyncExec[异步执行]

    SyncExec --> CheckExecuted{是否已执行?}
    CheckExecuted -->|是| ThrowError[抛出异常]
    CheckExecuted -->|否| MarkExecuted[标记已执行]

    AsyncExec --> EnqueueAsync[加入Dispatcher队列]
    EnqueueAsync --> CheckLimit{检查并发限制}
    CheckLimit -->|达到上限| AddToReady[加入就绪队列]
    CheckLimit -->|未达上限| AddToRunning[加入运行队列]
    AddToRunning --> ExecuteInPool[线程池执行]

    MarkExecuted --> BuildChain[构建拦截器链]
    ExecuteInPool --> BuildChain

    BuildChain --> Interceptor1[RetryAndFollowUp<br/>重试和重定向]
    Interceptor1 --> Interceptor2[BridgeInterceptor<br/>桥接拦截器]
    Interceptor2 --> Interceptor3[CacheInterceptor<br/>缓存拦截器]

    Interceptor3 --> CheckCache{检查缓存}
    CheckCache -->|有效缓存| ReturnCache[返回缓存响应]
    CheckCache -->|无缓存/失效| Interceptor4[ConnectInterceptor<br/>连接拦截器]

    Interceptor4 --> FindConnection{查找连接}
    FindConnection -->|池中有可用连接| ReuseConnection[复用连接]
    FindConnection -->|无可用连接| CreateConnection[创建新连接]

    CreateConnection --> TCPConnect[建立TCP连接]
    TCPConnect --> CheckProtocol{协议类型?}
    CheckProtocol -->|HTTP| HTTP1[HTTP/1.1]
    CheckProtocol -->|HTTPS| TLSHandshake[TLS握手]
    TLSHandshake --> CheckHTTP2{是否支持HTTP/2?}
    CheckHTTP2 -->|是| HTTP2[HTTP/2]
    CheckHTTP2 -->|否| HTTP1

    ReuseConnection --> AddToPool[加入连接池]
    HTTP1 --> AddToPool
    HTTP2 --> AddToPool

    AddToPool --> Interceptor5[CallServerInterceptor<br/>请求服务器]

    Interceptor5 --> WriteRequest[写入请求]
    WriteRequest --> WriteHeaders[写入请求头]
    WriteHeaders --> CheckBody{有请求体?}
    CheckBody -->|是| WriteBody[写入请求体]
    CheckBody -->|否| ReadResponse[读取响应]
    WriteBody --> ReadResponse

    ReadResponse --> ReadHeaders[读取响应头]
    ReadHeaders --> ReadBody[读取响应体]

    ReadBody --> CheckStatus{检查状态码}
    CheckStatus -->|3xx| CheckRedirect{是否重定向?}
    CheckRedirect -->|是| Interceptor1
    CheckRedirect -->|否| ProcessResponse

    CheckStatus -->|2xx/4xx/5xx| ProcessResponse[处理响应]

    ReturnCache --> ProcessResponse
    ProcessResponse --> SaveCache{是否可缓存?}
    SaveCache -->|是| WriteCache[写入缓存]
    SaveCache -->|否| ReturnResponse

    WriteCache --> ReturnResponse[返回Response]

    ReturnResponse --> FinishCall{执行类型?}
    FinishCall -->|同步| RemoveSync[从同步队列移除]
    FinishCall -->|异步| RemoveAsync[从异步队列移除]

    RemoveAsync --> PromoteWaiting[提升等待队列]
    PromoteWaiting --> ExecuteNext[执行下一个请求]

    RemoveSync --> End([请求完成])
    ExecuteNext --> End

    style Start fill:#e1f5e1
    style End fill:#ffe1e1
    style CheckCache fill:#fff4e1
    style FindConnection fill:#e1f0ff
    style CheckStatus fill:#ffe1f0

核心类关系说明

1. OkHttpClient

  • 职责: 框架入口,管理全局配置
  • 核心成员:
    • Dispatcher: 调度器,管理异步请求队列
    • ConnectionPool: 连接池,管理连接复用
    • List<Interceptor>: 应用拦截器列表
    • List<Interceptor>: 网络拦截器列表
    • Cache: 缓存管理器
  • 配置项:
    • 超时时间(连接、读、写)
    • 代理设置
    • SSL配置
    • Cookie管理器
    • DNS解析器

2. RealCall

  • 职责: 真正的Call实现,封装单个HTTP请求
  • 核心方法:
    • execute(): 同步执行
    • enqueue(Callback): 异步执行
    • cancel(): 取消请求
    • getResponseWithInterceptorChain(): 执行拦截器链
  • 状态管理:
    • executed: 是否已执行
    • canceled: 是否已取消

3. Dispatcher

  • 职责: 请求调度器,管理并发策略
  • 核心成员:
    • ExecutorService: 线程池
    • Deque<AsyncCall> readyAsyncCalls: 等待队列
    • Deque<AsyncCall> runningAsyncCalls: 运行队列
    • Deque<RealCall> runningSyncCalls: 同步调用队列
  • 并发控制:
    • 最大并发请求数: 64
    • 单Host最大并发: 5
    • promoteAndExecute(): 提升等待队列中的请求

4. RealInterceptorChain

  • 职责: 拦截器链的实现,责任链模式
  • 核心成员:
    • List<Interceptor> interceptors: 拦截器列表
    • int index: 当前拦截器索引
    • Request request: 当前请求
    • Call call: 关联的Call对象
  • 核心方法:
    • proceed(Request): 继续执行下一个拦截器

5. 内置拦截器

RetryAndFollowUpInterceptor
  • 职责: 重试和重定向
  • 功能:
    • 创建StreamAllocation
    • 处理连接失败重试
    • 处理重定向(3xx状态码)
    • 最大重定向次数: 20
BridgeInterceptor
  • 职责: 桥接应用层和网络层
  • 功能:
    • 添加必要的请求头(Host、Content-Type等)
    • 处理Cookie
    • 处理gzip压缩
    • 保存响应Cookie
CacheInterceptor
  • 职责: 缓存管理
  • 功能:
    • 读取缓存
    • 缓存策略(CacheStrategy)
    • 处理304 Not Modified
    • 写入缓存
ConnectInterceptor
  • 职责: 建立连接
  • 功能:
    • 从连接池获取连接
    • 创建新连接(TCP、TLS)
    • HTTP/2协商
    • 将连接加入连接池
CallServerInterceptor
  • 职责: 发送请求和接收响应
  • 功能:
    • 写入请求头和请求体
    • 读取响应头和响应体
    • 处理100-continue
    • 处理分块传输编码

6. ConnectionPool

  • 职责: HTTP连接池管理
  • 核心配置:
    • 最大空闲连接数: 5
    • 连接保活时间: 5分钟
  • 核心方法:
    • get(Address, Call): 获取可用连接
    • put(RealConnection): 添加连接到池
    • cleanup(): 清理过期连接
  • 清理策略:
    • 后台线程定期清理
    • 清理空闲超时的连接
    • 清理超过最大空闲数的连接

7. RealConnection

  • 职责: 真正的物理连接
  • 核心成员:
    • Socket rawSocket: TCP Socket
    • Socket socket: 可能是TLS包装的Socket
    • Protocol protocol: HTTP/1.1 或 HTTP/2
    • Http2Connection http2Connection: HTTP/2连接
  • 生命周期:
    • 建立连接(connect)
    • 执行请求(可复用)
    • 空闲回收

8. Cache

  • 职责: HTTP缓存实现
  • 底层实现: DiskLruCache
  • 缓存键: URL的MD5哈希
  • 缓存内容:
    • 响应头(Journal文件)
    • 响应体(单独的缓存文件)
  • 缓存策略:
    • 遵循HTTP缓存规范
    • Cache-Control、Expires、ETag、Last-Modified

9. Http2Connection

  • 职责: HTTP/2连接管理
  • 核心特性:
    • 多路复用: 单个连接支持多个流
    • 流量控制: Window size管理
    • 服务器推送
    • 头部压缩(HPACK)
  • 核心成员:
    • Map<Integer, Http2Stream> streams: 流映射表
    • Settings peerSettings: 对端配置
    • Settings okHttpSettings: 本地配置

10. WebSocket

  • 职责: WebSocket协议支持
  • 核心组件:
    • RealWebSocket: WebSocket实现
    • WebSocketReader: 读取WebSocket帧
    • WebSocketWriter: 写入WebSocket帧
  • 帧类型:
    • TEXT: 文本消息
    • BINARY: 二进制消息
    • PING/PONG: 心跳
    • CLOSE: 关闭连接

OkHttp 特性总结

并发策略

  • 异步请求: 通过Dispatcher管理线程池
  • 最大并发: 全局64个,单Host 5个
  • 队列管理: 等待队列自动提升到运行队列

连接管理

  • 连接复用: ConnectionPool管理连接池
  • HTTP/1.1: Keep-Alive保持连接
  • HTTP/2: 多路复用,单连接多流
  • 自动清理: 后台线程定期清理过期连接

缓存策略

  • DiskLruCache: 基于磁盘的LRU缓存
  • HTTP规范: 遵循RFC 7234缓存规范
  • 条件请求: 支持If-None-Match、If-Modified-Since
  • 透明压缩: 自动处理gzip压缩

协议支持

  • HTTP/1.1: 基础协议
  • HTTP/2: 多路复用、服务器推送
  • HTTPS: TLS/SSL支持
  • WebSocket: 全双工通信

拦截器机制

  • 责任链模式: 灵活的请求/响应处理
  • 应用拦截器: 最外层,看到的是应用层的请求/响应
  • 网络拦截器: 网络层,看到的是实际网络传输的请求/响应
  • 内置拦截器: 重试、桥接、缓存、连接、请求服务器

本文档深入剖析了OkHttp3框架的内部工作机制,涵盖了从客户端创建到请求执行的完整流程,包括连接池、缓存、HTTP/2、WebSocket等高级特性。