网络诊断方案选型

1. 概述

一个app的表现,往往和网络状态密切相关。这里的网络诊断主要是针对特定的域名或者ip,也就是说app的网络诊断是对当前网络到域名指向的服务端的连通性和带宽情况。

这里分几个层面来说。首先是哪些信息用来诊断网络,其次这些信息的诊断选择什么工具,再次网络诊断出来的数据如何理解。最后还需要给网络状况一个标准,以便于用户理解这个网络问题。

2. 网络诊断的工具

常用的网络工具或者方式,包括ping、DNS、traceroute、网络测速

2.1.ping测试

ping命令是基于ICMP,是在网络层。ping的运作原理是向目标主机传出一个ICMP echo@要求数据包,并等待接收echo回应数据包。程序会按时间和成功响应的次数估算丢失数据包率(丢包率)和数据包往返时间(网络时延,Round-trip delay time)。 (1)能验证网络的连通性 (2)会统计响应时间和TTL(IP包中的Time To Live,生存周期) 那么如何验证的呢? (1)ping命令会先发送一个 ICMP Echo Request给对端 (2)对端接收到之后, 会返回一个ICMP Echo Reply (3)若没有返回,就是超时了,会认为指定的网络地址不存在。

而端口号,是传输层的内容。所以在ICMP中根本就不关注端口号这样的信息。

ping示意

(4)TTL的理解。当我们对网络上的主机进行ping操作的时候,本地机器会发出一个数据包,数据包经过一定数量的路由器传送到目的主机,但是由于很多的原因,一些数据包不能正常传送到目的主机,那如果不给这些数据包一个生存时间的话,这些数据包会一直在网络上传送,导致网络开销的增大。当数据包传送到一个路由器之后,TTL就自动减1,如果减到0了还是没有传送到目的主机,那么就自动丢失。 PING中的TTL:Linux系统的TTL值为64或255。注意这里TTL值 指的是目标主机到本地数据的路由跳数,比如上例中ping 百度的结果 ,即为的为64-52=12 意味着,从本地机到百度服务器经过了12跳路由。解释下这里的TTL: ping中的TTL为一个为ICMP回显应答(ICMP Echo Reply)的TTL,这是目标机发回来的数据包的TTL。而我们发过去的TTL是由我们本地机类型决定,并不会显示在ping结果。

2.2.DNS解析

DNS(Domain Name System),它的作用就是根据域名,查出对应的 IP 地址,它是 HTTP 协议的前提。只有将域名正确的解析成 IP 地址后,后面的 HTTP 流程才可以继续进行下去。

DNS 服务器的要求,一定是高可用、高并发和分布式的服务器。它被分为多个层次结构。

  • 根 DNS 服务器:返回顶级域 DNS 服务器的 IP 地址。
  • 顶级域 DNS 服务器:返回权威 DNS 服务器的 IP 地址。
  • 权威 DNS 服务器:返回相应主机的 IP 地址。

这三类 DNS 服务器,类似一种树状的结构,分级存在。

DNS

当开始 DNS 解析的时候,如果 LocalDNS 没有缓存,那就会向 LocalDNS 服务器请求(通常就是运营商),如果还是没有,就会一级一级的,从根域名查对应的顶级域名,再从顶级域名查权威域名服务器,最后通过权威域名服务器,获取具体域名对应的 IP 地址。

查找过程

DNS 在提供域名和 IP 地址映射的过程中,其实提供了很多基于域名的功能,例如服务器的负载均衡,但是它也带来了一些问题。更多问题这里不展开,见参考文章[2]

查询DNS信息一般用下面两个命令

  • nslookup命令用于查询DNS的记录
  • dig命令 在adb shell环境下测试发现并不支持以上两种命令。可用方案
  • (1)利用so库 执行底层的命令
  • (2)安装Linux层第三方库,使Android系统支持上述命令
  • (3)dnsjava

这两种方法分别有他们的缺点so库麻烦,并且体积大,而第二种方式需要root权限。

2.3.traceroute拨测

通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。linux系统中,我们称之为traceroute,在MS Windows中为tracert。 traceroute通过发送小的数据包到目的设备直到其返回,来测量其需要多长时间。 traceroute也是基于ICMP协议实现的。 功能: 打印出可执行程序主机,一直到目标主机之前经历多少路由器。 traceroute命令,但android不支持traceroute只有root设备支持它。 https://github.com/wangjing53406/traceroute-for-android 上述库用JNI的生成SO来支持。 busybox实用程序包括traceroute。需要进一步验证

2.4.网络测速

主要测试上传下载带宽,例如 手机端网络测试工具 (android、iOS) 测速网 Android上利用Trafficstats流量测速度:上行、下行,下载一个文件,然后进行测试 Trafficstats.getUidRxBytes(uid)获取当前线程的

  • (1).获得当前的总接受数据,getTotalRxPackets()
  • (2).每隔几秒再获取一次总接收的数据
  • (3).讲最新获取的数据减去之前获取的数据并且除以间隔的秒数,就得到了每秒平均的网速b/s,最后进行单位 转换为kb、Mb等等

3. 网络诊断数据如何分析

3.1 ping

用来测试当前网络的ip到目标网络的可达及延迟,例如,华佗的https://ping.huatuo.qq.com/

ping测试

3.2 DNS

用来看域名解析是否正常,有无异常的劫持等

3.3 traceroute

用来看,每次路由经过的机器的ip,中间环节是否有问题,中间节点的是不是成为带宽的瓶颈,看是否要及时改变调度策略

3.4 网络测速

一些测速网站会选择最近的运营商进行测试。测试结果会受用户计算机性能、资源使用情况、网络高峰期、网站服务能力、线路等因素影响;所以,测试结果比实际速度略低。 测速的原理是 向服务器节点发送一批探测包,然后统计回包的质量,并将测速的结果通过回调接口通知出来。

测速的结果将会用于优化接下来的服务器选择策略,因此在一些高带宽场景下会(如视频通话)先进行一次测速,这将有助于选择最佳的服务器。同时,如果测试结果非常不理想,可以通过醒目的 UI 提示用户选择更好的网络。

由于 测速服务同时可以连接的云端服务器通常有超过三个以上的节点,测试过程是一台接一台串联进行的,所以测速结果的返回值会分多次回调通知出来。

4. 现有网络诊断组件或者方案对比

  • (1)HttpInfo 比较强大,记录的信息包括 Index信息(域名以及请求时间) Net信息(手机网络信息) Ping信息 Http信息 Host信息 MtuScan信息 PortScan信息 TraceRoute信息 NsLookup信息
  • (2)NetworkDiagnosis(内网) ping测试 DNS解析 traceroute拨测 网络测速 满足大部分场景,代码公开,只有Android端
  • (3)LDNetDiagnoService_Android 功能:ping、tcp connect和traceroute

Android的实现方案一: 是通过后台线程执行ping命令的方式模拟traceroute的过程,缺点就是模拟过程较慢,timeout的出现比较频繁 Android的实现方案二: 通过编译开源网络检测库iputilsC代码的方式对traceroute进行了套接字发送ICMP报文模拟,可以明显提高检测速度;(关于iputils工具原理实现,请参考博文) 这里用的方案2

  • (3)facebook/network-connection-class gitHub地址 用Android的接口实现的功能,只能测试下行的带宽
  • (4)华佗诊断系统 https://ping.huatuo.qq.com/ 功能:获取客户端IP,ldns,域名请求ip,请求耗时 特点:无需客户端,直接浏览器请求 缺点:有时会获取不到ip,dns信息,或不准确

5. 根据现有业务如何选择

像直播或者短视频的应用,对网络要求比较高。需要对上述的几个维度都进行分析。而一般信息流或者IM的app对网络要求实时性不高的仅仅可只测试ping

6. 参考文章

[1] 移动端下各类诊断方法与工具 [2] Android 网络优化,使用 HTTPDNS 优化 DNS,从原理到 OkHttp 集成 [3] Android获得DNS地址 [4] DNS(二)通过dig命令理解DNS [5] Android网络测试与诊断 [6] 通话前网络测速