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](/../../../images/image-20230920144449262.png)
抓包工具
1 2 3 4
| 1.Charles 2.Fiddler 3.Wireshark 4.TcpDump
|
Charles使用
1 2 3
| 1.断点功能 2.Map Local 3.弱网环境模拟
|
启动软件后发送请求,会自动抓包![image-20230920144728904](/../../../images/image-20230920144728904.png)
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:
|
三、精准获取流量消耗实战
问题思考
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
| 数据缓存、增量更新、压缩、图片相关等 需要结合实际情况进行选择
|
五、网络请求质量优化实战
质量指标
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
| 方案:只抓单独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 用户反馈消耗流量多这种问题怎么查 - 精准流量获取能力 - 所有请求大小及次数的监控 - 主动预警能力
|