7.网络优化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//网络优化
1.网络缓存:
1.服务端返回加上过期时间,避免每次重新获取
2.OkHttp、Retfort、Volley都有较好实践
3.无网络时展示数据缓存;
2.网络质量:
1.时长、业务成功率、失败率的统计,在OkHttp、Retfort、Volley等自行统计相关数据并在特定场景合并上报;
2.弱网络模拟
3.增量更新:
1.加上版本的概念,只传输有变化的数据
4.数据压缩:
1.Post请求Body使用GZip压缩(字符压缩)
2.图片上传之前必须压缩
5.图片相关:
1.图片使用策略细化:优先缩略图
2.使用WebP格式图片

一、网络优化从哪些纬度开展

正确认识

1
2
3
4
5
6
1.网络优化的纬度:多维
2.仅仅重视流量不够
3.网络流量的消耗量:精确
4.整体均值掩盖单点问题
5.网络相关监控:全面
6.粗粒度监控不能帮助我们发现、解决深层次问题

网络优化纬度

1
2
3
4
5
6
7
8
9
10
流量消耗
- 一段时间流量消耗的精准度量,网络类型、前后台
- 监控相关:用户流量消耗均值、异常率( 消耗多、次数多)
- 完整链路全部监控(Request、Response),主动上报
网络请求质量
- 用户体验:请求速度、成功率
- 监控相关: 请求时长、业务成功率、失败率、T失败接口
其它
- 公司成本:带宽、服务器数、CDN
- 耗电

网络优化误区

1
2
1.只关注流量消耗,忽视其它纬度
2.只关注均值、整体,忽视个体

二、网络优化工具选择

Network Profiler

1
2
3
1.显示实时网络活动:发送、接收数据及连接数
2.需要启用高级分析(androidStudio顶部-run-Edit Configurations...->勾上(Profiling-Enable advanced profiling (required for API level < 26 only))
3.只支持 HttpURLConnection和OkHttp网络库

发送一个请求后在prifoler中出现下图情况,选中请求的时间端后可以查看到请求的状态及大小等信息;image-20230920144449262

抓包工具

1
2
3
4
1.Charles
2.Fiddler
3.Wireshark
4.TcpDump

Charles使用

1
2
3
1.断点功能
2.Map Local
3.弱网环境模拟

启动软件后发送请求,会自动抓包image-20230920144728904

Stetho

1
2
强大的应用调试桥,连接Android和Chrome
网络监控、视图查看、数据库查看、命令行扩展等

Stetho使用

1
2
3
4
1.com.facebook.stetho:stetho-okhttp3:1.5.0
2.Stetho.initializeWithDefaults(this):
3.addNetworkInterceptor
4.Chrome浏览器:chrome://inspect(需翻墙)

三、精准获取流量消耗实战

问题思考

1
2
3
4
如何判断App流量消耗偏高
- 绝对值看不出高低
- 对比竞品,相同Case对比流量消耗
- 异常监控超过正常指标(线上)

测试方案

1
2
3
1.设置-流量管理
2.抓包工具:只允许本App联网
3.可以解决大多数问题,但是线上场景线下可能遇不到

线上流量获取方案

1
2
3
4
5
6
7
8
9
10
TrafficStats:API8以上重启以来的流量数据统计
- TrafficStats:API8以上重启以来的流量数据统计
- getUidRxBytes(int uid)指定Uid的接收流量
- getTotalTxBytes0)总发送流量
缺点:
- 无法获取某个时间段内的流量消耗
NetworkStatsManager:API23之后流量统计(推荐)
- 可获取指定时间间隔内的流量信息
- 可获取不同网络类型下的消耗
- 使用示例查看百度

前后台流量获取方案

1
2
3
1.难题:线上反馈App后台跑流量
2.只获取一个时间段的值不够全面
后台定时任务->获取间隔内流量->记录前后台->分别计算->上报APM后台->流量治理依据

前后台流量获取方案总结

1
2
1.有一定误差,可接受范围内
2.结合精细化的流量异常报警针对性的解决后台跑流量

四、网络请求流量优化实战

使用网络的场景概述

1
2
3
数据:Api、资源包(升级包、H5、RN)、配置信息
图片:下载、上传
监控:APM相关、单点问题相关

数据缓存

1
2
3
1.服务端返回加上过期时间,避免每次重新获取
2.节约流量且大幅提高数据访问速度,更好的用户体验
3.OkHttp、Volley都有较好实践

无网络时使用缓存数据示例,不同框架不一样,只做参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.optimize.performance.net;

import com.optimize.performance.PerformanceApp;
import com.optimize.performance.utils.Utils;
import java.io.IOException;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class NoNetInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
if(!Utils.isNetworkConnected(PerformanceApp.getApplication())){
builder.cacheControl(CacheControl.FORCE_CACHE);
}
return chain.proceed(builder.build());
}
}

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();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
Cache cache = new Cache(PerformanceApp.getApplication().getCacheDir(),10*1024*1024);
client.
eventListenerFactory(OkHttpEventListener.FACTORY).
dns(OkHttpDNS.getIns(PerformanceApp.getApplication())).
addInterceptor(new NoNetInterceptor()).
addInterceptor(logging);

final Retrofit RETROFIT = new Retrofit.Builder()
.baseUrl(HTTP_SPORTSNBA_QQ_COM)
.addConverterFactory(FastJsonConverterFactory.create())
.client(client.build())
.build();
API_SERVICE = RETROFIT.create(APIService.class);
}
}

增量数据更新

1
2
1.加上版本的概念,只传输有变化的数据
2.配置信息、省市区县等更新

数据压缩

1
2
3
1.Post请求Body使用GZip压缩
2.请求头压缩
3.图片上传之前必须压缩

优化发送频率和时机

1
2
1.合并网络请求、减少请求次数
2.性能日志上报:批量+特定场景上报

图片相关

1
2
1.图片使用策略细化:优先缩略图
2.使用WebP格式图片

总结

1
2
数据缓存、增量更新、压缩、图片相关等
需要结合实际情况进行选择

五、网络请求质量优化实战

质量指标

1
2
1.网络请求成功率
2.网络请求速度

Http请求过程

1
2
3
1.请求到达运营商的Dns服务器并解析成对应的IP地址
2.创建连接,根据IP地址找到相应的服务器,发起一个请求
3.服务器找到对应的资源原路返回访问的用户

DNS相关

1
2
3
问题:DNS被劫持、DNS解析慢
方案:使用HttpDNS,绕过运营商域名解析过程
优势:降低平均访问时长、提高连接成功率
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//示例:
package com.optimize.performance.net;
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);
}
}

协议版本升级

1
2
3
- 1.0:版本TCP连接不复用
- 1.1:引入持久连接,但数据通讯按次序进行
- 2:多工,客户端、服务器双向实时通信

网络请求质量监控

1
2
接口请求耗时、成功率、错误码
图片加载的每一步耗时

网络容灾机制

1
2
备用服务器分流
多次失败后一定时间内不进行请求,避免雪崩效应

其它

1
2
CDN加速、提高带宽、动静资源分离(更新后清理缓存)
减少传输量,注意请求时机及频率

总结

1
2
网络请求质量指标
提升网络请求质量的方式

六、网络体系化方案建设

线下测试

1
2
方案:只抓单独App
侧重点:请求有误、多余,网络切换、弱网、无网测试

线上监控

1
2
3
4
5
6
7
8
9
10
11
12
服务端监控
- 请求耗时(区分地域、时间段、版本、机型
- 失败率(业务失败与请求失败)
- Top失败接口、异常接口
客户端监控
- 接口的每一步详细信息(DNS、连接、请求等)
- 请求次数、网络包大小、失败原因
- 图片监控
异常监控体系
- 服务器防刷:超限拒绝访问
- 客户端:大文件预警、异常兜底策略
- 单点问题追查

七、问题

1
2
3
4
5
6
7
8
9
10
11
12
在网络方面你们做了哪些监控,建立了哪些指标
- 演进过程、优化背景
- 质量:请求成功率、每步耗时、状态码
- 流量:精确统计、前后台
如何有效的降低用户流量消耗
- 数据:缓存、增量更新
- 上传:压缩
- 图片:缩略图、webp
用户反馈消耗流量多这种问题怎么查
- 精准流量获取能力
- 所有请求大小及次数的监控
- 主动预警能力