质量指标
网络请求成功率
网络请求速度
Http请求过程
请求到达运营商的Dns服务器并解析成对应的IP地址
创建连接,根据IP地址找到相应的服务器,发起一个请求
服务器找到对应的资源原路返回访问的用户
DNS相关
问题:DNS被劫持、DNS解析慢
方案:使用HttpDNS,绕过运营商域名解析过程
优势:降低平均访问时长、提高连接成功率
示例:
compile ( 'com.aliyun.ams:alicloud-android-httpdns:1.1.7@aar' ) {
transitive **true
**}
import android.content.Context;
import com.alibaba.sdk.android.httpdns.HttpDns;
import com.alibaba.sdk.android.httpdns.HttpDnsService;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import okhttp3.Dns;
public class OkHttpDNS implements Dns {
private HttpDnsService dnsService;
private static OkHttpDNS instance = null;
private OkHttpDNS(Context context) {
dnsService = HttpDns.getService(context, "");
}
public static OkHttpDNS getIns(Context context) {
if (instance == null) {
synchronized (OkHttpDNS.class) {
if (instance == null) {
instance = new OkHttpDNS(context);
}
}
}
return instance;
}
@Override
public List<InetAddress> lookup(String hostname) throws UnknownHostException {
String ip = dnsService.getIpByHostAsync(hostname);
if(ip != null){
List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
return inetAddresses;
}
return Dns.SYSTEM.lookup(hostname);
}
}
public class RetrofitNewsUtils {
private static final APIService API_SERVICE;
public static APIService getApiService() {
return API_SERVICE;
}
public static final String HTTP_SPORTSNBA_QQ_COM = "http://sportsnba.qq.com/";
static {
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.dns(OkHttpDNS.getIns(PerformanceApp.getApplication()));
final Retrofit RETROFIT = new Retrofit.Builder()
.baseUrl(HTTP_SPORTSNBA_QQ_COM)
.addConverterFactory(FastJsonConverterFactory.create())
.client(client.build())
.build();
API_SERVICE = RETROFIT.create(APIService.class);
}
}
http协议版本升级
1.0:TCP连接不复用
1.1:引入持久连接,但数据通讯按次序进行
2:多工,客户端、服务器双向实时通信
网络请求质量监控
接口请求耗时、成功率、错误码
public class OkHttpEvent {
public long dnsStartTime;
public long dnsEndTime;
public long responseBodySize;
public boolean apiSuccess;
public String errorReason;
}
import android.util.Log;
import com.optimize.performance.utils.LogUtils;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.List;
import javax.annotation.Nullable;
import okhttp3.Call;
import okhttp3.Connection;
import okhttp3.EventListener;
import okhttp3.Handshake;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
public class OkHttpEventListener extends EventListener {
public static final Factory FACTORY = new Factory() {
@Override
public EventListener create(Call call) {
return new OkHttpEventListener();
}
};
OkHttpEvent okHttpEvent;
public OkHttpEventListener() {
super();
okHttpEvent = new OkHttpEvent();
}
@Override
public void callStart(Call call) {
super.callStart(call);
Log.i("lz","callStart");
}
@Override
public void dnsStart(Call call, String domainName) {
super.dnsStart(call, domainName);
okHttpEvent.dnsStartTime = System.currentTimeMillis();
}
@Override
public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
super.dnsEnd(call, domainName, inetAddressList);
okHttpEvent.dnsEndTime = System.currentTimeMillis();
}
@Override
public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) {
super.connectStart(call, inetSocketAddress, proxy);
}
@Override
public void secureConnectStart(Call call) {
super.secureConnectStart(call);
}
@Override
public void secureConnectEnd(Call call, @Nullable Handshake handshake) {
super.secureConnectEnd(call, handshake);
}
@Override
public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol) {
super.connectEnd(call, inetSocketAddress, proxy, protocol);
}
@Override
public void connectFailed(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol, IOException ioe) {
super.connectFailed(call, inetSocketAddress, proxy, protocol, ioe);
}
@Override
public void connectionAcquired(Call call, Connection connection) {
super.connectionAcquired(call, connection);
}
@Override
public void connectionReleased(Call call, Connection connection) {
super.connectionReleased(call, connection);
}
@Override
public void requestHeadersStart(Call call) {
super.requestHeadersStart(call);
}
@Override
public void requestHeadersEnd(Call call, Request request) {
super.requestHeadersEnd(call, request);
}
@Override
public void requestBodyStart(Call call) {
super.requestBodyStart(call);
}
@Override
public void requestBodyEnd(Call call, long byteCount) {
super.requestBodyEnd(call, byteCount);
}
@Override
public void responseHeadersStart(Call call) {
super.responseHeadersStart(call);
}
@Override
public void responseHeadersEnd(Call call, Response response) {
super.responseHeadersEnd(call, response);
}
@Override
public void responseBodyStart(Call call) {
super.responseBodyStart(call);
}
@Override
public void responseBodyEnd(Call call, long byteCount) {
super.responseBodyEnd(call, byteCount);
okHttpEvent.responseBodySize = byteCount;
}
@Override
public void callEnd(Call call) {
super.callEnd(call);
okHttpEvent.apiSuccess = true;
}
@Override
public void callFailed(Call call, IOException ioe) {
Log.i("lz","callFailed ");
super.callFailed(call, ioe);
okHttpEvent.apiSuccess = false;
okHttpEvent.errorReason = Log.getStackTraceString(ioe);
Log.i("lz","reason "+okHttpEvent.errorReason);
}
}
package com.optimize.performance.net;
import com.optimize.performance.PerformanceApp;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.fastjson.FastJsonConverterFactory;
public class RetrofitNewsUtils {
private static final APIService API_SERVICE;
public static APIService getApiService() {
return API_SERVICE;
}
public static final String HTTP_SPORTSNBA_QQ_COM = "http://sportsnba.qq.com/";
static {
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.eventListenerFactory(OkHttpEventListener.FACTORY);
final Retrofit RETROFIT = new Retrofit.Builder()
.baseUrl(HTTP_SPORTSNBA_QQ_COM)
.addConverterFactory(FastJsonConverterFactory.create())
.client(client.build())
.build();
API_SERVICE = RETROFIT.create(APIService.class);
}
}
图片加载的每一步耗时
网络容灾机制
备用服务器分流
多次失败后一定时间内不进行请求,避免雪崩效应
其它
CDN加速、提高带宽、动静资源分离(更新后清理缓存)
减少传输量,注意请求时机及频率
OkHttp的请求池