Android 架构之高可用移动网络链接

《亿级Android架构》小专栏文章列表:html

《亿级 Android 架构》专栏随谈》git

《Android 架构之网络链接与加速》github

《Android 架构之高性能图片组件》缓存

《Android 架构之长链接技术》安全

《Android 架构之网络安全演进》服务器

《Android 架构之高性能移动端日志系统》微信

《Android 架构之秒级移动配置中心》网络

正文

读者好,前面咱们在《Android 架构之网络链接与加速》《Android 架构之长链接技术》两篇文章中,讲解了Http短链接、TCP长链接、链接复用与速度优化、数据压缩等方面的知识点。不过,真实的网络环境是很复杂的,存在各类各样的因素会致使网络服务不可用,好比DNS劫持、服务器宕机、弱网等。换言之,若是服务都不可用,那上面这些优化也就没有意义了。架构

所以,本文主要谈一下在真实的网络环境下,存在哪些常见的网络不可用缘由,以及大多数公司是如何解决并兜底,从而达到高可用链接这个目标的。并发

文章会从下面几方面进行阐述:

  • DNS劫持与可靠IP获取
    • HttpDNS
    • 内置IP列表+自动测速
  • IP列表的缓存更新策略
  • IP列表可用性兜底策略
  • 针对弱网的多IP复合链接测速
  • 自主网络诊断

DNS劫持与可靠IP获取

咱们知道,大多数的网络请求第一步就是DNS过程,通过1-RTT的时间将域名转化为IP地址,而后再去发起请求。可是,有相关经验的开发者应该了解,DNS过程不只耗时不稳定(3G下200ms,4G下100ms),并且可能解析失败,甚至被劫持,将用户导入到了错误的IP地址。若是攻击者本身作一个仿冒的网站,劫持你的DNS并将IP转到这个假网站上,可能会形成很大的用户数据泄漏和公司品牌损失。

为了解决这个问题,得到可靠的IP列表,现有大厂会采用下面一些方案:

1. HTTPDNS

好比阿里云和腾讯云都推出了本身的HttpDNS服务,在全国多地部署相关的服务器提供安全解析DNS服务。

基本的原理就是经过发起Http请求到HttpDNS服务器,获取某个域名对应的可用IP列表。这个IP列表能够根据用户当前的地点进行返回,并且默认会进行IP测速,按速度排序。同时,伴随这IP列表,服务器还会下发一个缓存有效时间 TTL,有了这个时间,客户端能够放心的将IP列表缓存在本地,并在即将过时前及时去更新IP列表,保证每次网络请求均可以使用当前最优的IP地址。

2. 内置IP列表+自动测速

固然,自建HttpDNS服务须要必定规模的机房部署、大量的客户端测速数据上报、全球IP库收集等,须要很多的投入。所以,有些公司好比携程就采用了更加轻量一点的方案:内置IP列表

具体原理以下:

在APK打包时会内置一份IP列表进去。当App启动时,这些IP的权重相同,此时会随机从里面获取IP来使用。可是这有个问题,对不一样地区的用户而言,最优IP确定是不一样的。好比对于上海的用户而言,上海区服务器的IP确定是最快的,而对于深圳的用户而言,华南区IP才是最快的。所以,在App运行过程当中,咱们会经过依次对IP列表逐个进行Ping测速,根据测速结果动态变动IP的权重,而后提供给网络链接使用。

IP列表的缓存更新策略

经过HttpDNS或内置IP列表的方案,咱们能够为网络层提供一份相对可靠的IP地址做为缓存,每次须要发起请求时,直接从缓存里读取这份IP列表便可创建IP直连。

那新的问题来了,移动网络是在不断变化的。最多见的场景,好比咱们从Wi-Fi切换到了4G,获取进入电梯后从4G降级成3G,或者咱们从A Wi-Fi换到了B Wi-Fi,这都意味着咱们的网络链路变动了。那么,以前缓存的IP列表是否仍然可用,或者仍然最优呢?

显然并不必定,好比从Wi-Fi切到了移动4G,背后整条网络链路都不一样了,以前的IP列表颇有可能不是最优的了,极端状况下可能某些IP地址也不可用了。所以,咱们须要最好IP列表的及时更新,保证不管网络如何切换,咱们都能使用最优的IP地址列表。

具体有下面几种方式:

  1. 定时器监听HttpDNS返回的TTL过时时间。当IP列表即将过时前,发起请求获取下一轮的IP列表并进行更新;
  2. 监控网络链接状态,网络链路切换,好比Wi-Fi/3G/4G转换,若是是Wi-Fi,还能够监控SSID信息变动(针对不一样的Wi-Fi热点),及时触发IP列表刷新;在异步更新过程当中,能够仍然使用旧缓存IP提供服务;
  3. 配置中心下发,这种有时会用在服务器分流,好比某台服务器压力过大,能够经过配置中心系统下发新的IP列表给客户端访问。

另外,IP列表缓存应该对不一样网络类型、网络标识有对应的一份缓存,可使用网络类型(3G、4G、Wi-Fi等)+网络标识(SSID、ispCode等)做为缓存Key,当网络切换时,使用Key去查询缓存。

这些缓存能够持久化到多个文件,以Key做为文件名,同时能够基于当前网络状态,缓存一份IP列表到内存供使用,当网络状态变化,则刷新内存缓存。

IP列表可用性兜底策略

经过更新机制,咱们能够保证本地IP列表缓存动态更新的及时性。那么,若是HttpDNS服务器出现故障呢,或者首次打开App,HttpDNS尚未完成,或者大面积DNS劫持等,怎么办呢?

因此说,除了及时获取最优IP列表,咱们还要考虑,若是获取不到IP列表,如何进行兜底?保证用户的网络请求不受影响。

在线上运行中,能够采起下面四组IP兜底策略,按优先级排列以下:

  • HttpDNS IP:即大厂自建的HttpDNS服务获取动态IP;
  • DNS IP:即常规Local DNS获取IP;
  • Auth IP:经过配置下发的动态保底IP列表;
  • Hardcode IP:本地写死的保底IP列表

前面两种动态IP不用多说,你们都清楚,这二者能够动态获取IP,效果最好。可是,若是发生故障,致使这两个方案都不可用,好比大面积DNS劫持之类的,这时客户端必须可以自动降级到静态兜底IP,保证网络服务可用。

但这也可能存在一个问题,就是静态兜底IP对应服务器访问量可能会忽然暴增,若是峰值过高可能形成更大的危害如雪崩。所以,除了内置静态兜底IP,还须要为客户端提供一个可经过配置动态下发兜底IP列表,能够作到负载均衡,将流量分散到不一样机器上。并且这些静态IP贵精不贵多,而且要有高可用的后台服务保证,做为全局网络服务的兜底。

针对弱网的多IP复合链接测速

经过上面的几套方案,能够保证用户可以高可用的获取最优IP列表,提升用户访问速度,并且能应对各类复杂的网络状态。

那么如今考虑这样一种状况,上面的IP列表咱们可以正常的获取,可是,用户处于弱网状态下,IP链接成功率很低,怎么办呢?

针对弱网通常有两种方式:

  • 串行链接:先链接第一个IP,直到发生了超时,再去对第二个IP建连;
  • 并行链接:同时对多个IP创建链接,哪一个连成功了就用哪一个;

这两种方案的缺点是:串行链接可能须要很长时间的试错,才能找到可用的IP,并且这里还取决于如何选择超时时间,若是超时时间较长,则须要很长时间才能找到可用IP;若是很短,则可能会漏掉一些相对优质的IP,不断去尝试新IP,恶性循环;而并行链接则会对服务端形成极大的链接负载压力和必定程度的浪费,对于电量也有必定程度开销。

所以,这里咱们介绍下Mars里的复合链接策略做为学习参考:

在弱网状态下,依次发起对5组IP+Port的链接,10s做为超时时间。当前一个链接发起了4s钟还未成功,则当即发起下一个链接,以此类推。当其中有一个链接创建成功,则当即中止其余链接。这样的方式能够兼备串行链接和并行链接的优点:较快找到可用IP,同时对于服务器不会形成过大的链接压力。至于这个超时时间10s,则能够经过上报数据来动态统计,找到一个合理的超时时间。

自主网络诊断

在真实的线上环境咱们发现,即便IP和后台服务均有效,仍有一部分用户的网络链接会出现失败。而此时单纯从IP地址已经分析不出缘由,颇有多是该用户的网络链路上存在问题致使链接失败。

这时就须要咱们主动去探测这个用户的网络链接并诊断整条链接链路。

所以,为了准确了解线上网络错误的用户的真实状况,咱们会在客户端里内置网络诊断策略,经过Ping或者TraceRoute探测用户手机到服务器的整条网络链路上的状况,并将数据存储上报,用于分析用户的真实网络错误缘由。

Ping你们比较熟悉,目的是为了测试另外一台主机是否可达,向目标主机发送Echo包并等待回包;而TraceRoute能够获取数据包在IP网络通过的路由器的IP地址,原理以下:

  • 程序是利用增长存活时间(TTL)值来实现其功能的。每当数据包通过一个路由器,其存活时间就会减1。当其存活时间是0时,主机便取消数据包,并发送一个ICMP TTL数据包给原数据包的发出者。
  • 程序发出的首3个数据包TTL值是1,以后3个是2,如此类推,它便获得一连串数据包路径。注意IP不保证每一个数据包走的路径都同样。

在Android上通常有两种方式来实现这个诊断:

  1. 经过后台线程执行ping命令的方式,模拟traceroute的过程;
  2. 经过编译开源网络检测库iputilsC代码的方式对traceroute进行了套接字发送ICMP报文模拟。

感兴趣的能够参考文末提供的开源项目LDNetDiagnoService,经过诊断能够把日志上报用于分析,并做出相关的调整和优化。

小结

本文针对如何提升网络链接的高可用性作了讲解和分析,线上方案最重要考虑的就是兜底,不管发生何种问题,都要保证网络服务可用。若是用户连咱们的服务器都链接不上,那可能会带来很是严重的灾难;固然,咱们也要考虑服务器负载,不能形成服务器压力过大,致使雪崩之类的问题。

有相关疑问欢迎随时留言。


谢谢。

wingjay


《亿级Android架构》小专栏介绍

业务的快速增加离不开稳定可靠的架构。《亿级Android架构》小专栏会基于做者实际工做经验,结合国内大厂如阿里、腾讯、美团等基础架构现状,尝试谈谈如何设计一套好的架构来支持业务从0到1,甚至到亿,但愿与你们多多探讨。

本专栏主要内容:

  1. 当前大厂有哪些Android架构;
  2. 这些架构能解决什么问题;
  3. 这些架构的原理是什么;
  4. 学习这些架构对咱们自身的意义。

《亿级Android架构》小专栏文章列表:

《亿级 Android 架构》专栏随谈》

《Android 架构之网络链接与加速》

《Android 架构之长链接技术》

《Android 架构之高性能图片组件》

《Android 架构之网络安全演进》

《Android 架构之高性能移动端日志系统》


参考文章

《微信终端跨平台组件 Mars 系列(三)链接超时与IP&Port排序》

《海量之道系列文章之弱联网优化》

《LDNetDiagnoService_Android》

《美团点评移动网络优化实践》

相关文章
相关标签/搜索