App域名容灾方案

8,415 阅读7分钟

文 掘金号 wandyers @每日优鲜

著作权归作者所有。商业转载请联系本账号获得授权,非商业转载请注明每日优鲜大前端团队以及原文地址。

注:本文为系列文章,将分为方案简介,方案落地方案,具体方案剖析,技术实现细节等多篇文章,敬请期待。

背景

因部分地区App域名解析出现问题,导致部分B端App等(以下统一简称App)都出现网络请求超时,找不到主机或异常错误,导致部分配送App无法登录、使用等问题,影响了部分To B业务。

目标

尽量消除因外部网络原因(如外部DNS解析异常、域名不可达等)导致的App出现网络异常的问题。 经过调研,我们总结了下面的几种方案来防止类似问题再次发生,对比之后,我们最终也选择了部分策略做为我们的分批落地方案(步骤后续会详细讲解)。 我们的希望App达到避免DNS劫持,降低访问延迟,降低用户连接失败率,提升用户体验度,SDK高可扩展度及可复用性。

方案简介

以下的各种实现策略的简介及简单的优缺点对比。

方案详细

本章节将对上面提到的策略做出详细阐述,包括实现流程及部分重点细节。

1.系统DNS缓存策略

本策略即现在的实现策略,无需额外开发,使用域名进行请求,依赖系统DNS和网络服务商的DNS解析等。不再详细说明。

2. 直连策略

直连方案实现较为简单,当使用域名访问出现找不到主机,请求超时等异常时,直接切换至IP地址重试请求;且App在下次启动之前,一直使用该IP进行网络请求。

IP或域名优先级为: LocalDNS(域名) > 内置固定IP。

流程图如下图所示:

本方案实现较为简单,在紧急时可以作为临时过度方案。但不建议长期使用此策略,因为App内置的IP无法实时动态更新,会增加未来的风险。

3. 配置文件策略

App首次启动时(包含冷启动),请求后端接口下发配置文件,数据格式可参照附录一定义,并持久化缓存在App客户端本地以供将来使用。

当App启动时,从缓存读取出来配置,并验证有效期。如全部过期,则使用域名或系统内置的IP使用;如部分未过期或全未过期(其实大部分情况下,即使IP过期,在一定时间段内还是有效的),则按照优先级次序使用IP地址直连请求;

IP或域名优先级为: 配置文件IP > LocalDNS(域名)> 内置固定IP 。

此方案相比较直连方案,更加灵活,后台可随时更换IP地址而不影响生产环境客户端。

但会出现当域名不可达时间段较长时,或者用户在较长时间段内未打开App,而打开时正好域名不可达,导致缓存配置文件的全部失效,进而降级至直连方案。简而言之,配置文件TTL时间阀值不好控制,不够灵活。

因为每次App启动都会请求配置文件并更新本地缓存,无法根据每个IP的TTL灵活的更新。

这种方案也会与项目耦合度较高,不利于扩展,各端都需要实现自己业务逻辑,与实际业务耦合度较高。

缓存文件或数据的安全性校验也必不可少(此部分将在后续的分享中详细阐述),防止被第三方恶意篡改导致出现异常。

参考流程如下图所示:

以下两种策略都是基于HttpDNS。HttpDNS是以Http或Https的方式向外提供域名解析的服务。与传统的运营商的Local DNS相比,有以下几点优势:

一、 防止出现DNS劫持

二、 可实现精准调度,让客户端接入最近的业务节点

三、 0ms解析延迟

四、 快速生效

五、 扩展性强

4.第三方HttpDNS策略

腾讯云HttpDNS,阿里云HttpDNS,DNSPod等厂家提供HttpDNS方案,客户端接入方便,开发量较小,相对稳定。

但由于依赖第三方服务,不能自定义一些依赖规则,比如分流等。且第三方服务也可能出现服务异常进而导致我们的网络状态不可控。

拓扑图如下图所示【图片参考于网络】:

流程图与自建HttpDNS方案相似,请参考"自建HttpDNS"章节流程图。

5.自建HttpDNS策略

自建HttpDNS就是提供私有的DNS解析服务,以Http或Https的方式向外提供服务。严格来讲,此方案不是降级策略,而是使用自建DNS替代系统DNS拿到直连IP进行网络请求,而把系统级的缓存作为最后的降级方案。

独立域名或独立IP提供HttpDNS域名解析服务,自研HttpDNS的SDK实现与服务器的通讯;各端App接入SDK并完成Http DNS的解析工作,并根据域名拿到部分或全部可用的IP地址列表,不再依赖现有域名访问后台服务,每次均采用IP的方式访问服务。

拓扑图如下图所示【图片参考于网络】:

App在启动时,需要按照以下流程完成SDK初始化,访问业务接口时,直接使用IP访问,降低延迟,避免DNS劫持等问题,也能方便的集成在其它App中。

IP或域名优先级为:自建HttpDNS > LocalDNS(域名) > 内置固定IP 。

主要流程图如下图所示:

自定HttpDNS与配置文件策略的区别在于,第一提供SDK供多端快捷接入;第二能对单个IP的生命周期进行管理;第三SDK接入方不需要关心IP的管理,只要根据SDK返回的IP或域名(无有效IP时自动切换为域名)进行网络请求即可。

关注问题

  1. 无论采用哪种方案,都需要考虑Header中Host参数配置问题,Https的证书校验问题,SNI等问题,App内嵌的网页的网络请求等问题。
  2. 无论采用何种方案,都默认使用App内部固定的IP作为最后的容灾方案。
  3. 相同优先级中存在多个IP有效时,采取轮询或优先级的方案就行分流。

上面提到的问题,都将在后续的分享中说明相关实现方案。

建议方案

基于以上阐述,考虑App现状,建议初始阶段暂时采用直连策略(DS001)或配置文件策略(DS002),在既能减少生产环境问题。App能正常访问的前提下。

第二步根据实际情况,建议尽快实现或接入第三方HttpDNS策略方案(DS003)或自建Http DNS方案(DS004),并实现自己的SDK供多端使用,此方案在灵活性,扩展性,可维护性,可控制性上比其它方案更加有优势。

附录

附录一

[
	{
		"hostName":"a.test.cn", //域名
		"ips":[ // 域名对应的IP地址列表
			{
				"priority":1, // 优先级
				"ipAddr":"192.168.1.23", // ip地址
				"ttl":1568859453 // 超时时间
			},
			{
				"priority":1,
				"ipAddr":"192.168.1.23",
				" ttl":1568859453
			}
		]
	},
	{
		"hostName": "b.test.cn" ,
		"ips":[
			{
		    	"priority":1,
				"ipAddr":"192.168.1.23",
				" ttl":1568859453
			}
		]
	}
]