1)架构分层(你要记住的几个核心角色)
-
API 层:OkHttpClient(不可变、Builder 配置)、Request/Response(不可变)、Call(一次请求任务,可 execute() 同步或 enqueue() 异步)。推荐复用一个 Client,newBuilder() 派生会共享连接池与线程池,减少握手与内存开销。
-
拦截器链(Interceptors) :按顺序串起来的责任链,两类——应用拦截器(一次调用只走一次、可短路/重试)与 网络拦截器(每次真正的网络请求都会走一遍,能拿到底层 Connection)。拦截器负责监控、改写与重试。
-
并发与调度:Dispatcher 管理异步并发上限(默认 总 64、同 host 5),内部用线程池执行;同步调用在调用方线程。
-
连接系统:ConnectionPool 负责连接复用与空闲回收;Address/Route 把“URL + Client 配置”拆成静态地址与动态路由;HTTP/2 在一条连接上多路复用,HTTP/1.1 每次一个流。
-
缓存与 Cookie:磁盘 Cache 可选(默认关闭),遵循现代 HTTP 缓存语义;CookieJar 负责读写 cookie。
-
安全(HTTPS) :支持 TLS1.3/ALPN、ConnectionSpec、HostnameVerifier、CertificatePinner;可按需降级/自定义套件。
-
可观测性:EventListener 按阶段发事件(DNS、连接获取/释放、缓存命中等),用于埋点与排障。
2)一次请求是怎样跑起来的(从newCall()到复用连接)
-
你构造 Request 并 client.newCall(request)。
-
拦截器链按顺序执行:应用拦截器 →(可能有缓存命中)→ 网络拦截器 → 发送请求/读取响应。链上每个节点都通过 chain.proceed() 传递下去。
-
选连接:先用 URL + Client 配成 Address,再从 ConnectionPool 里找可复用连接;找不到就挑一条 Route(DNS/代理/TLS 版本),新建连接并握手。请求结束后把连接放回池子。
-
HTTP/2 多路复用:同一连接可跑多个并发流;HTTP/1.1 要等响应体读完并关闭后才能复用。
-
并发控制:异步请求进入 Dispatcher 的等待/运行队列,受 maxRequests / maxRequestsPerHost 约束。
-
故障恢复与回退:重定向/认证质询/连接失败会自动重试;在 OkHttp 5 中还有 Fast Fallback(Happy Eyeballs) ,并发竞速 IPv6/IPv4,谁先连通用谁。
小细节:要让连接进入可复用状态,务必把响应体读完并关闭(否则不会回到连接池)。
3)默认策略为何如此(背后的工程取舍)
-
Client 复用:单一 OkHttpClient + newBuilder() 派生,能共享连接池/线程池 → 更高命中率、更低延迟与内存占用。
-
拦截器分层:应用拦截器屏蔽中间响应(重定向/重试),关注“应用意图”;网络拦截器贴近“线上传输”,能看到压缩/连接信息——这样的分层让功能解耦、可测试。
-
并发默认值(64 / 5) :对多数客户端既能避免过度并发占用资源,又兼顾 HTTP/2 的并发流;需要时再按场景调高。
-
连接抽象(URL/Address/Route) :把静态与动态要素拆开,便于复用与容错(多 IP、代理认证、TLS 协商失败时的回退)。
-
缓存:遵循现代 HTTP 规范,默认关闭避免误用;开启后用事件流能直观看到命中/条件命中等路径。
-
安全:默认现代 TLS,必要时按 ConnectionSpec 回退;官方建议保持库版本更新以适应 TLS 生态变化。
4)什么时候该自定义(以及怎么改)
-
高并发单域名 / 短连接多:适当提高 Dispatcher.maxRequests / maxRequestsPerHost;不要指望连接池限制并发,它只管空闲连接。
-
需要端到端观测:接入 EventListener 记录 DNS、连接获取/释放、缓存命中与失败原因。
-
网络复杂/跨 IPv6/IPv4:升级到 5.x,默认有 Fast Fallback 的更快建连体验。
-
HTTPS 特殊要求:通过 connectionSpecs、CertificatePinner、HostnameVerifier 精细化配置。
-
缓存策略:为离线/省流量场景开启 Cache,并结合服务端的 Cache-Control;调试时看文档中的“Cache Events”。
5)一段“拿来就用”的配置模板
val client = OkHttpClient.Builder()
// 可观察:埋点全链路事件
.eventListener(object : EventListener() {/* override想看的事件 */})
// 应用拦截器(重试、鉴权、日志等)
.addInterceptor( /* your app interceptor */ )
// 可选:网络拦截器(只做与网络强相关的逻辑)
//.addNetworkInterceptor(/* e.g. HttpLoggingInterceptor() */)
// 缓存(可选)
//.cache(Cache(File(cacheDir, "http_cache"), 50L * 1024 * 1024))
// 并发策略
.dispatcher(Dispatcher().apply {
maxRequests = 64
maxRequestsPerHost = 10
})
// 连接/HTTPS 策略(示例)
//.connectionSpecs(listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS))
// 超时(连接默认 10s,可按需调整)
.connectTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
.build()
(并发与缓存配置参考官方 API/文档;连接/HTTPS 策略与默认连接超时见对应条目。 )