Android开发经验谈Android开发Android技术知识

Android性能优化:网络优化(三、网络优化篇)上

2020-12-25  本文已影响0人  下饭小当家

成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~。

一、网络优化维度

1、网络优化分析

基础网络的效率就像一辆列车,时延是火车的速度 (启动时间),而带宽就像火车的车厢装载量,整个传输的物理链路就像火车的铁轨。从网络的通信过程来看,共涉及到 三个模块

而对于网络的优化,我们可以从以下五个维度来进行。

1)、流量优化

精确获取网络流量的消耗量,解决整体均值掩盖单点异常流量的问题。

2)、网络监控

建设全面的网络监控,因为粗粒度的监控不能够帮助我们发现和解决问题。

3)、流量消耗

4)、网络请求质量

5)、其它

2、网络优化误区

二、网络优化工具

1、Network Profiler

特点

打开高级分析

Run => Edit Cofigurations => 界面最右边 Profiling => 打开 Enable advanced profiling (required for API level < 26 only)

使用 Network Profiler 调试 WanAndroid 网络请求

选中目标网络请求,可以看到在下方的 Connection View 一栏看到对应的网络数据,如下所示:

选中 Connection View 特定的一条数据即可在右边看到该请求对应的网络数据。

Overview

该网络请求的预览信息

普通 Json 数据请求

图片加载请求

Response

Response Header 与 Body 信息

Request

Request Header 与 Body 信息

CallStack

网络请求的调用堆栈信息, 下图就是 Awesome-WanAndroid 发起一个网络请求所经历的调用堆栈:

Awesome-WanAndroid 使用 Glide 发起一个图片加载请求所经历的调用堆栈:

关键细节

高级配置中的 required for API level < 26 only 不是限定调试的手机版本小于26,我使用 API 27 的手机也可以调试。

实践中获得的新知识及感悟

如果想快速搞懂接手项目中的网络/图片加载等框架的w网络请求流程,可以使用 Profiler NETWORK 的 CallStack 功能,并且双击其中任意的一行调用链方法都可以 jump to 指定源码。

选中网络请求无法显示数据?

打开高级分析即可。

2、Charles

使用 Java 开发的,MAC 上使用较多。

特点

安装配置

1、下载 Charles

2、截获手机端的网络包。

需要配置手机与电脑连接同一 WIFI。

1)、电脑端设置 Charles — 打开 HTTP 代理并设置代理端口
2)、手机端设置 WIFI 代理及端口
3)、设置完成,运行任意联网程序,Charles 会弹出请求连接的确认框,点击 allow 即可。

3、截取 HTTPS

需要信任 Charles 的 CA 证书。

1)、打开 SSL 代理,并配置 Host 与 Port
2)、信任 Charles Proxy CA 机构
3)、手机端安装 Charles 颁发的 SSL 证书
4)、手机端安装证书

实践过程

选中目标网络请求

从 Overview 中可以看到很全面抓包信息 。

使用断点功能

1)、右键点击要断点的 URL,选中 BreakPoints 开启断点功能。
2)、点击顶部 Proxy => Breadkpoint Settings。
3)、双击 Breakpoints Settings 面板中的目标

URL,在弹出的 Edit Breakpoint 面板中进行编辑。

4)、这里默认选择断点 Request 与 Response,我们可以选择仅断点 Response 或 Request。点击确认即断点设置完成。
5)、然后,我们就可以点击主面板右侧的 Edit Response 编辑 Response,修改完成后点击最下方的 Execute 即可。

使用 Map Local

1)、自由模拟服务端的返回数据,以提前进行接口测试。
1)、右键点击要使用 Map Local 的 URL,选中Map Local 开启断点功能。
1)、然后,我们在 Edit Mapping 面板中选择 Map To 的 Local path,选择本地设定的 maplocal 本地数据(例如 JsonString)

弱网模拟功能

碰到的问题

3、Wireshark

强烈推荐 geektime-webprotocol

WireShark 主要可以用来对四种流进行跟踪,如下所示:

1)、WireShark 基本使用

如何捕获报文

Wireshark 面板

快捷方式工具栏

数据包的颜色(视图->着色规则)

设定时间显示格式

数据包列表面板的标记符号

文件操作

如何快速抓取移动设备的报文?

2)、Wireshark 过滤器

如果表达式的背景为绿色,则说明过滤器的语法是正确的,红色则说明有错误。

捕获过滤器

它用于减少抓取的报文体积,使用 BPF(Berkeley Packet Filter) 语法,功能相对有限。

BPF 可以在设备驱动级别提供抓包过滤接口,多数抓包工具都支持此语法。而 BPF 的 Expression 表达式由多个 primitives 原语组成。而每一个 primitives 原语则由名称或数字,以及描述它的多个 qualifiers 限定词组成。

qualifiers 限定词

简单示例

src or dst portrange 6000-8000 && tcp or ip6
复制代码

显示过滤器

它对已经抓取到的报文进行过滤显示,功能强大。

基于协议域过滤
显示过滤器的过滤属性

任何在报文细节面板中解析出的字段名,都可以作为过滤属性。在视图->内部->支持的协议面板里,可以看到各字段名对应的属性名。例如,在报文细节面板中 TCP 协议头中的 Source Port,对应着过滤属性为 tcp.srcport。

常用操作符
可用函数
显示过滤器的可视化对话框
环形缓冲器

例如使用 3 个文件的环形缓存器,从 **.1 => **.2 => **.3 然后又从 **.1 文件开始记录,形成环形。

4、TcpDump(网络数据包嗅探器)

1)、抓包步骤

1、获取 ROOT 权限的手机一部

2、下载 tcpdump

3、将 tcpdump 安装到手机上

adb push tcpdump /data/local/tmp
复制代码

4、修改 tcpdump 的权限,使其具有可执行的权限

chmod 777 /data/local/tmp/tcpdump
复制代码

5、执行 tcpdump 命令进行抓包,按组合键 Ctrl + C 可以停止抓包

6、将抓到的数据包的信息保存为 Pcap 文件,这里仅需在执行 tcpdump 后加上 -w 参数

tcpdump-w /data/local/tmp/tcp.pcap
复制代码

7、把 Pcap 复制到 电脑上,使用 Wireshark 分析数据包的流量。

2)、捕获及停止条件

3)、文件操作

strftime 参数指定文件名。

4)、输出时间戳格式

5)、分析信息详情

5、Stetho

6、其它的性能检测工具

三、精准获取流量消耗

1、如何判断 App 流量消耗偏高?

2、测试方案

3、线上流量获取方案

1)、TrafficStats

特点

API

缺点

无法获取某个时间段内的流量消耗。

2)、NetworkStatsManager

API 23 之后。

特点

NetUtils.getStats

获取指定时间间隔的 蜂窝 + WIFI 流量总信息

4、前后台流量获取方案

问题:线上反馈 App 后天流量消耗大?

只获取一个时间段的流量不够全面。

实现原理

后台定时任务 => 获取时间间隔内流量 => 记录前后台 => 分别计算 => 上报 APM 后台 => 流量治理依据

小结

成功 log 如下所示:

2020-05-11 10:47:55.633 4036-4181/json.chao.com.wanandroid I/WanAndroid-LOG: │ [MainActivity.java | 193 | lambda$initEventAndData$1$MainActivity] backNetUseData: 4 MB
2020-05-11 10:47:55.646 4036-4181/json.chao.com.wanandroid I/WanAndroid-LOG: │ [MainActivity.java | 194 | lambda$initEventAndData$1$MainActivity] foreNetUseData: 4 MB
2020-05-11 10:47:55.652 4036-4181/json.chao.com.wanandroid I/WanAndroid-LOG: │ [MainActivity.java | 197 | lambda$initEventAndData$1$MainActivity] totalNetUseData: 8 MB
复制代码

四、网络请求流量优化

1、常见使用网络的场景

1)、数据压缩

POST 请求 Body 使用 GZip 压缩,同时服务端返回 Body 也使用 GZip 压缩。

2)、图片

3)、性能日志上报:批量 + 特定场景上报

APM 相关、单点问题相关。例如埋点数据可以等到某一时机点(例如 开启了 WIFI、数据量过大必须上传一部分时)再上传。

4)、数据缓存

服务端返回加上过期时间,避免每次重新获取。 节约流量且大幅提高数据访问速度,更好的用户体验。

Request 缓存设置

当 Request 的头部是 2 和 3 时,如果服务器的资源没有修改,则服务器会返回 HTTP/304 Not Modified,客户端会使用缓存的 Response。

Response 缓存设置

HTTP Response 是否可以缓存是由 Response 的头部控制的,服务器可以通过 Expires 和 Cache-Control 控制 Response 如何在客户端缓存。

Expires

Expires 头部会包含一个日期,即该资源缓存的有效期,客户端有新的相同请求时,如果资源缓存没有过期,则使用缓存资源,服务器不会返回任何东西。

Cache-Control

Cache-Control 可以标明 Response 如何存储及其如何使用,其选项如下所示:

OKHttp 无网数据缓存实现

POST 在 OKHttp 中默认不会缓存,因为 POST 一般是用来修改数据的。在 Awesome-WanAndroid 中的 HttpModule—cacheInterceptor 中就已经实现了 OKHttp 的无网数据缓存,代码如下所示:

File cacheFile = new File(Constants.PATH_CACHE);
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
Interceptor cacheInterceptor = chain -> {
    Request request = chain.request();
    if (!CommonUtils.isNetworkConnected()) {
        // 无网时强制使用数据缓存,以提升用户体验。
        request = request.newBuilder()
                .cacheControl(CacheControl.FORCE_CACHE)
                .build();
    }
    Response response = chain.proceed(request);
    if (CommonUtils.isNetworkConnected()) {
        int maxAge = 0;
        // 有网络时, 不缓存, 最大保存时长为0
        response.newBuilder()
                .header("Cache-Control", "public, max-age=" + maxAge)
                .removeHeader("Pragma")
                .build();
    } else {
        // 无网络时,设置超时为4周
        int maxStale = 60 * 60 * 24 * 28;
        response.newBuilder()
                .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                .removeHeader("Pragma")
                .build();
    }
    return response;
};
// 缓存优化
builder.addNetworkInterceptor(cacheInterceptor);
builder.addInterceptor(cacheInterceptor);
builder.cache(cache);
复制代码

5)、离线包、增量数据更新

加上版本的概念,仅传输有变化的数据。

6)、请求头压缩

如果请求头不变,服务端可以使用映射缓存 请求头 MD5 : 请求头,之后请求头都使用 MD5 即可。

7)、优化发送频率和时机

8)、合并网络请求、减少请求次数。

9)、流量兜底能力

如果发现流量异常,我们可以通过后台服务器终止协议交互,以避免问题恶化。

2、流量统计

我们可以利用 network-connection-class 进行流量统计,它内部使用的是 API 8 的 TrafficStats 类,用于获取整个手机或者某个 UID 从开机算起的网络流量。

1)、四个核心 API

// 从开机开始Mobile网络接收的字节总数,不包括Wifi
getMobileRxBytes()        
// 从开机开始所有网络接收的字节总数,包括Wifi
getTotalRxBytes()     
// 从开机开始Mobile网络发送的字节总数,不包括Wifi
getMobileTxBytes()        
// 从开机开始所有网络发送的字节总数,包括Wifi
getTotalTxBytes()         
复制代码

2)、对应的Linux 内核 proc 统计接口

// stats接口提供各个uid在各个网络接口(wlan0, ppp0等)的流量信息
/proc/net/xt_qtaguid/stats
// iface_stat_fmt接口提供各个接口的汇总流量信息
proc/net/xt_qtaguid/iface_stat_fmt
复制代码

3)、工作原理

作者:jsonchao
链接:https://juejin.cn/post/6844904182822993933
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上一篇 下一篇

猜你喜欢

热点阅读