OkHttp 都是复用连接池惹得祸
2020-07-23 本文已影响0人
fyg
测试提的一个bug说android app 比ios 调接口普遍要慢。
用抓包工具对比 android 和ios手机调接口情况发现确实慢,印象中主要是慢在DNS解析上了,大家看一下如下代码,有没有发现问题呢。
问题1
如上代码设置相当于没有复用 keep-alive导致每次请求都需要重新进行 DNS解析,3次握手4次挥手操作,这样是非常浪费性能的,
源码中默认的是5个空闲TCP接连,并且活跃时间为5分钟。
问题2
上面代码initEngine(Context context) 方法 可以看到OkHttpClient并没有复用,每次请求都是创建一个新 OkHttpClient ,正常情况下我们应该只使用一个 OkHttpClient 引擎就行了,这里也是需要优化的地方。
修改后的代码下如:
增加了OkHttpJXBaseHttpEngine层,该层主要是让
OkHttpJXFileHttpEngine
OkHttpJXFileHttpEngine
OkHttpJXStringHttpEngine
共用同一个 HTTPClient 处理app的业务接口
由于app埋点前期使用的 公司内部研发的 九章统计,针对统计的埋点,走的是另外一个OkHttpClient。
有问必答:
1 如果同一时间调用了同一个域名下的10个耗时的接口时,是否会开启新的tcp连接? 还是等这些连接空闲后在去请求新的接口?
源码中同一域名下默认是5个TCP接连,超过后会等待,
不同域名下最多64个请求
Dispatcher类
public void setMaxRequests(int maxRequests)
synchronized void enqueue(AsyncCall call) {
// 正在执行的总任务数及相同host下正在执行的任务数小于阈值时,直接执行任务
if(runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else { // 加入等待队列
readyAsyncCalls.add(call);
}
}
当正在执行的任务总数及相同host下的任务数小于最大值时,
直接执行当前请求,而任务数超过限定时,将其加入等待队列。
OkHttp Request 请求执行流程
OKHTTP系列(二)
OkHttp完全解析(四)连接Connections
2 okhttp连接池复用是具体的一个连接还是同一个域名下的连接都可以复用?
是同一个域名下连接都可以复用,服务器和PC浏览器同一个域名下只能建立6个TCP 连接,为了让同一个网页中的图片快速加载,所以要把图片放到不同的域名下,这样就可以实现>6个的连接请求。