AlexiaChen / AlexiaChen.github.io

My Blog https://github.com/AlexiaChen/AlexiaChen.github.io/issues
87 stars 11 forks source link

架构设计-----业务高可用 #83

Open AlexiaChen opened 4 years ago

AlexiaChen commented 4 years ago

异地多活

异地就是指地理位置的不同,多活就是不同的地理位置上的系统都能够提供业务服务,这里的活是Active的意思。

这种方案真是要真正的大型互联网公司才有这种架构了,抗自然灾害能力比较强。

异地多活架构

同城异区

现在城市都有区嘛,昆明有五华,盘龙等。一般各个区的网络或者电路都是松耦合的。所以会在各个区部署多个机房,距离一般都是几十公里,通过搭建高速网络,能够实现和同机房的网络传输速度。如果该城市遭遇地震,水灾,一般就废了。

跨城异地

业务部署在不同的城市的多个机房,距离最好远离些,因为能有效面对极端灾难事件。但是这样的架构复杂,而且网络传输速度会降低,因为现实世界都是各种路由和中转,不可控因素增加。比如广州到北京的正常情况下RTT大约是50ms,如果有网络抖动,RTT可能飙升到500ms甚至1s,如果还有线路丢包,那延迟可能就是几秒几十秒了。

既然物理世界决定了延迟不低,那么在这个时间窗口内数据不一致,还要能正常提供服务,这样就比较矛盾:数据不一致业务肯定不会正常,但是跨城异地肯定会导致数据不一致。

如何解决?重点还是在“数据”类型上,根据数据的业务特性来做不同的架构。如果是金融行业一些强一致需求,比如,银行存款余额,支付宝余额等,这类数据实际上是无法做到跨城异地多活的。所以对于余额这类数据,最多只能采用同城异区这种架构。

而对数据一致性要求不高,数据变更不频繁,甚至数据丢失影响也不大的业务,跨城异地多活就能用上了。比如,用户登录,新闻网站,微博,百度贴吧等等。

跨国异地

业务部署在不同国家的多个机房。哈,这个距离一般更远了,网络延时更大,延时平均在几秒,对于用户感觉特别明显,很显然,这样的架构就连微博,贴吧都不适用了。一般用在为不同地区的用户提供服务,比如:微软的Bing搜索有国内版和国际版,亚马逊有美亚,日亚。还有一个场景就是,为只读类业务做多活,比如Google的搜索业务,爬虫爬到的那些网页索引,不需要实时,搜索结果基本相同,访问哪里都差不多。

异地多活设计技巧

1. 保证核心业务异地多活

前提不要犯一个错误:保证所有业务“异地多活”。这种显然是最终要完蛋的,有些业务特性做异地多活可能无解。

所以要优先实现核心业务的异地多活架构。

2. 核心数据最终一致性

前提不要犯一个错误:所有数据实时同步。也是扯淡的。你应该考虑尽量减少数据同步,只同步核心业务相关的数据,保证最终一致性。

3. 采用多种手段同步数据

基本上主流的存储系统都有同步功能,MySQL主从复制,Redis的Cluster功能,Elastic Search的集群功能。这些系统的同步功能已经非常强大了,能够拿来直接用,但是也限制了一些人的想象力:只使用存储系统的同步功能

绝大部分场景下,存储系统自带的同步功能足够了,但是一些极端场景,难以满足业务需求。解决方案就是手脚并用,多种方案一起上。比如,用消息队列方式,二次读取,回源读取等。

4. 只保证绝大部分用户的异地多活

前提不要犯一个错误:保证业务100%可用。这是不现实的。事实上也绝对不可能保证100%可用。做到百分之99%就可以了,其他的可以用变相手段搞定,比如,挂公告,事后对用户进行补偿。

接口级的故障应对方案

异地多活架构主要是应对系统故障,发生概率比较小,还有另一种故障影响没系统级那么大,但是发生的概率较高,这就是接口级故障。

接口故障表现就是系统没有宕机,网络没有中断,但是业务表现出问题了。比如,业务响应慢,大量访问超时,大量访问出现异常,无法连接数据库等等。

引起这种原因,要不是系统负载过大,要不就是程序bug。但是解决接口故障的核心思想也是:优先保证核心业务,优先保证绝大部分用户。

降级

某些业务或接口的功能降低,只提供部分功能,也可以完全停掉所有功能。核心思想是弃车保帅,优先保证核心业务。

熔断

和降级这个概念比较容易混淆,降级的目的是应对系统自身的故障,熔断的目的是应对依赖的外部系统的故障情况。比如A服务依赖并调用B服务和C服务,但是B服务响应慢,间接导致A服务响应慢,这时候就需要熔断机制,即A服务不再请求B服务这个接口,或者请求B服务就立刻返回错误,避免拖慢整个A服务。A服务中依赖C服务的业务不会受到影响。

现今的微服务框架一般都用这种功能,比如Spring Cloud。

限流

一般是为了对抗用户访问压力,限制流量。到一定流量阈值就丢弃请求。算法有很多,什么令牌桶什么的。不过多描述。

限流分两种: