立即咨询

电话咨询

微信咨询

立即试用
商务合作

谢文辉:高可用系统架构实践丨声网开发者创业讲堂 Vol.02

2022-06-08

在整个技术体系,特别是完善的技术能力体系中,有 3 点是系统和分布式系统都会非常看重的。

 

● 高性能,提升整个系统的并发响应;

● 高可用,提升整个系统的可使用能力;

● 可维护性,系统上线后进行方便、高效的运营维护。

 

这 3 点中,系统的可用性是第一要位。不管系统规模大小,特别是初创团队的系统很多都需要从 0 到 1 进行构建,可用性都是最为重要的指标。本期内容,我们将分享在高可用方面的一些架构实践。

 

 

 

 

在正式开始前,我们先分享一个故事。

 

2015 年 5 月 27 日下午,支付宝出现了一个大规模的宕机事故。有用户反馈,支付宝有一些支付和登录功能不能用了。经过排查发现,问题的原因是杭州萧山区的光纤在维修时被挖断了。经过应急响应,5 月 27 日的晚上 7 点多,系统才被修复。

 

因为这个事件,阿里集团将每年的 5 月 27 日定义为「故障日」,以此来纪念和提醒所有的技术人,在技术相关体系中要关注线上系统的稳定性和可靠性。

 

2020 年天猫双 11,阿里出现了出现了机房断电事故。但这次事故其实是一场人为的演练,通过手动切断电源来检查整个系统的稳定性表现。在这次模拟演练中,系统的整体表现还是非常不错的。

 

这两个故事给我们提供了一个很重要的警示:系统的高可用应该成为系统设计里的第一原则。

 

系统的“高可用”应该怎样定义呢?我认为应该是在系统允许的时间范围内对外提供服务的能力。那么,为什么一定要强调“允许的时间范围”?试想一下,如果系统响应一个请求需要花费 5 分钟或者 10 分钟,那这种可用性的意义就已经不是很大了。在一个高并发服务的系统场景下,我们强调的系统阈值是用户体验允许的时间范围。

 

对系统故障的定义一般采用“ N 个 9” 方式来表示,例如 2 个 9 (99%)的系统可用性,代表全年就有 87 小时的系统故障,“5 个 9”(99.999%)代表全年的系统故障时间不会超过 6 分钟,“6 个 9”就已经非常小了,这对系统技术的设计要求是非常高的。

 

阿里集团内部对于故障处理提出了一个“1-5-10”方法论。不管是在什么情况下,1 分钟之内感知系统的问题并告警,5 分钟之内快速定位故障原因,10 分钟之内修复这些故障。从“1-5-10”的定义来说,其中还涉及了系统可维护性、系统监控和告警等方面的内容。

 

系统的分布式理论可以为高可用提供一些原则性的指导:

 

(1) CAP 理论

 

● 数据一致性(Consistency)

 系统可用性(Availability)

 系统的连通性,也称为分区的容忍性(Partition tolerance)。

 

这里是取三者的⾸字⺟,将其称为 CAP 理论。CAP 理论指出,这三者⽆法同时实现,只能取其⼆,在分布式多副本场景中,分布式系统架构下,由于⽹络连通性问题是不可避免的,也就是说⽹络抖动导致的数据分区是客观存在的,所以⼀般来说分布式多副本场景下 CAP 最终关注的是 AP 或者 CP 的选择问题。

 

我们把 CAP 理论的 3 个点拆开来看:

 

假设选择 C 和 A 并舍弃 P,说明这个系统没有所谓的分区,即不需要分区,这个系统基本上是单点或者说单机能力的一个系统。假设是一个分布式系统,P 一定要考虑它本身存在分区的特点。因此,再扩展一下,如果是分布式系统,那么就是多机或者多集群,甚至是多机房的情况。

 

再来看看满足 C、P 并舍弃 A 的情况,即舍弃系统的可用性,在常见的抢票、抢购等高并发的系统中,可能出现不能访问等故障。还有可能满足 A、P 并舍弃 C, 即舍弃数据一致性,这种情况下要求数据一致性不敏感。例如,一个账号的授权系统对于数据一致性的要求不是很高,就可以舍弃这一点。

 

(2) BASE 理论,它是 CAP 理论的延伸。BASE 理论也有 3 个要素:

 

● 基本可用 (Basically Available)

● 软状态 (Soft State)

● 最终一致性(Eventually Consistent)

 

BASE 理论关注数据的最终一致性。其中基本可用相对于高可用,也就是当出现系统故障的时候要保障仍然可用。比如以前可能 10 毫秒就能响应,现在需要 1 秒才能响应,但仍处于一个基本可用的状态。

 

软状态与原子性处理(一次处理全部成功或者全部失败)对应。软状态允许中间存在一些不一致的状态,这也是 BASE 理论中一个很重要的中间态。最终一致性相对的就是强一致性,通过技术的手段,能够让它以软状态达到最终的一致性。

 

 

 

 

接下来我想跟大家聊一聊系统分层调回的一些常见实现方案,其中包括业务逻辑层数据存储层以及机房层

 

 

上图是系统分层示意图。我们在进行系统设计时,都会先做一个接入层,比如 RPC 或者 Restful 之类。接入层还有一些其他的概念,如 Nginx 或者 Lvs,可以叫作接入层组件。但我们现在把这个接入层作为系统实现的接入层,中间还有一个服务层,把接入层和服务层统一叫作业务逻辑,实现这样的一块功能的层叫作业务逻辑层。不管是基于缓存还是基于数据库,最终都要落地到数据存储中。

 

除了这样分布在一个服务或者一个集群范围内的系统,我们再把视角放大一点,这里还有一个机房的概念,例如华东机房、华北机房、华南机房。不同的机房都会布这样的系统,实现机房之间容错或者故障切分。我们从这几个层来讨论业务逻辑层怎么做、数据存储层怎么做、机房的容灾或者流量的切换有哪些比较常见的做法。

 

业务逻辑层

 

对于业务逻辑层,这里有必要讲一讲“有状态”“无状态”。系统首先要实现高可用,就应该把系统做成无状态的,因为无状态能够更好地实现分布式系统的可用性扩展。

 

什么叫作有状态和无状态呢?

 

 

举个例子,假设用户的账号登录这样的一个系统,外部发送一个请求,有可能本次会请求到后端服务器的节点 1,也有可能会请求到节点 N。每一次请求的 session 的信息,很有可能就落在这样的一个单台服务器上。

 

如果每次请求或者每个人有不同的请求,会发现每台服务器的状态数据非常不一致。在节点 1 可能存了 10 个用户,节点 2 又存储其他的几个用户,导致数据非常不一致。这种服务器数据不一致的场景,我们称之为系统有状态。

 

那什么叫作无状态呢?例如刚才所说的账号登录了这个状态的数据,把会话数据剥离出来,系统处理例如分布式的 session 能力,其实就是中间的一套组件,直接将处理逻辑放在中间。那么,所有的数据存储放在一个状态数据存储里,例如可能会存储在缓存中,其实就把一个系统的有状态改为无状态,叫作无状态的处理。可以看到上图右边的无状态,对于整个系统的高可用的扩展,只需要中间这一层不断加服务器就可以。

 

有状态服务特点如下:

 

● 服务本身依赖或者需要存储状态化数据,如果出现故障只能通过其他备份的状态数据进行恢复。

● 一个请求只会被某个节点处理。

● 如果单节点出现故障需要进行状态数据迁移。

● 由于存在多节点的数据存储,所以需要考虑数据一致性的问题。

 

无状态服务特点如下:

 

● 服务不依赖自身状态,状态数据存储在公共化存储服务中。

● 任何一个请求都可以被任何一个节点处理。

● 服务之间实现高可用以及水平扩展无须额外操作。

 

有状态和无状态的转换有两种方式:

 

(1) 状态数据的相互同步,最开始能想到的就是状态数据由每台服务器来存储,1 到 N 台服务器中都有这个数据,每台服务器中的数据可能都完全不同,在服务器内存中的状态数据如何实现同步是一个比较难处理的问题。

 

(2) 统一存储,使用分布式的数据存储,把中间的状态数据全部存储在中间服务中,基于中间的服务直接访问到下面的存储服务层。显然,从上图的方案来看,第二种更为高效、简单、合理。

 

业务逻辑层实现服务的可用有两种方式 —— 服务降级和服务限流。服务降级是指当服务负载过高或者出现一些故障的时候,将一些非核心业务或者故障业务移除或者暂不处理的措施,为其他业务留出处理的能力。服务降级如果是 Java 体系,最常见的开源组件是 Hystrix。

 

服务降级有几种处理方式:

 

(1) 基于线程隔离的处理,例如登录验证密码和下单存储的功能。服务降级可以把这些模块细化,基于线程隔离的方式能够避免请求出现的流量过大导致线程过高的问题,从而保障业务的有效处理。

 

(2) 熔断,它能够计算系统的健康度。例如在过往的 1 分钟或几分钟,计算请求的失败数和所有请求的数量,形成对系统健康度的判断。健康度判断通过设置一个阈值(例如大于 10%、大于 50%等)来触发熔断机制。假设调用第三方的某一个服务,若超时率过高,熔断可以避免系统在下游出现问题后不断向上以滚雪球的方式影响上游业务,造成所有请求都无法处理。服务降级经常会使用这种方式来做数据库中数据层的降级,这是一种比较简单的方式。例如,在数据库的 DAO 层编写接口时,用降级和非降级两种方式实现。在 Service 层调用 DAO 时,使用配置中心手动触发数据库降级,从而实现数据库动态降级。

 

Spring 提供了一个比较好用的 Hot Swap 方式,它是一个代理。它可以把 hot swap target source 实现两个 Bean——数据库访问类和降级实现类。触发降级时,HostSwap可以自动获取一个降级的Bean。Hot Swap对上游的业务是透明的,它调用 DAO 层,至于 DAO 层里面的实现是降级层还是数据库的读写层是透明的,内部自动实现,这也是一种做法。

 

第三个网络层,我们以机房来举个例子。

 

 

上图中,机房 1 和机房 2 通过专线的方式来进行数据通信。专线容易出现可靠性问题,应该怎样解决呢?第一种方式是不通过专线进行通信,代价是功能上的一些损失。第二种方式是通过配置中心下发指令来启动降级,比如停止流量和数据之间的同步。如果网络质量达不到期望,但并未完全切断,那么可以通过令牌桶或者流量桶等方式对网络拥塞进行控制。

 

服务限流是服务降级的一种轻度表现形式。服务降级中最后说到的令牌桶是一种典型的服务限流方式。服务限流的目的与服务降级相同,是让尽量多的流量能够流入到后端可以处理的能力范围中。

 

服务限流一般有几种做法:计数器、漏桶模式、令牌桶模式。

 

● 计数器的实现非常简单,例如在多久的时间范围之内,在单位时间内做多少。

● 漏桶模式定义了一个漏桶,其容量是一定的,然后不断地往里面加可取的令牌。它的流量是一个固定的流速,也就是说它可以进行均衡的、精确的处理,例如可以使用漏桶模式,将每秒的流数控制为 10 QPS 或者 100 QPS。Nginx 中的 limit 模块组件基本都是用漏桶模式进行精准限流。

● 令牌桶模式区别于漏桶模式之处就是允许突发流量。例如,在“抢购”这种突发流量比较大的情况下,我们也要保护后台一些服务,此时可以使用令牌桶模式实现服务限流。

 

服务限流中还有一种做法 —— 流量整形,其原理如下图所示,左侧是业务服务器,右侧是日志服务器,业务服务器不断地产生很多日志。在流量和数据量很大的情况下,中间通过消息队列来实现削峰填谷,不断地传输数据,使后端形成比较良好的流量波形,方便后端的接纳和处理。

 

 

 

数据逻辑层

 

首先介绍双机架构的几种模式:

 

● 主备模式,一台是主数据库,另一台是备数据库。“备”代表备⽤,正常情况下⼀般不使⽤,只有在数据库出现故障时才启⽤备数据库。由于当主数据库出现问题时需要手动切换,因此对于线上处理的性能提升或者资源的使用,这种模式是有一些浪费的。主备模式的最大优势是简单,只需要接入一台主数据库。在 OA 系统等可用性或流量不是很大的业务场景中,主备模式可以简单地容纳手动处理的时延。

● 主从模式从主备模式衍生而来,将正常场景下的备用数据库提升为可用的从数据库。当主数据库和从数据库出现问题时,主从切换有几种做法,例如通过第三方探测主数据库是否处于正常连接状态,从数据库是否出现问题,然后进行切换。

● 双主模式。如下图所示,双主模式的实现较为复杂,两台数据库要双向进行数据同步。

 

 

双主数据由于需要双向同步,会面临业务数据一致性如何做、数据的循环复制等一系列问题。另外,主从模式会存在怎样探测其服务器的处理问题。处理不当很有可能会出现脑裂的情况,两台服务器相互探测不到对方,只关注自己是否可以处理。我们认为比起用服务器自己的方式去探测(例如心跳探测),用第三方独立的服务探测其实会更合理,通过第三方的独立服务进行探测,从而解决所谓的脑裂问题。

 

多副本也是一种提高系统可用性的重要模式。副本是分布式系统容错、提高可用性的基本手段。一般数据副本的基本策略是以机器为单位,每个副本存储在不同的机器上,副本间的数据保持完全一致。在分布式系统中,副本一般采用切片的方式来做,如下图所示。

 

 

上图展示了切片后的数据。例如,原来分片 0 ~ 分片 2 可以分在不同的节点中,每个节点存储和处理的数据量较小。1000 QPS 分到 3 个节点,每个节点便可以只处理 300 多个分片。多副本模式还可以快速恢复数据。假设分片 0 出现了一些问题,甚至节点 0 和节点 1 都出现了问题,恢复数据时不需要把全部数据恢复。

 

在分布式系统中,分片多副本模式是解决数据之间可用性的一个较好的方案。

 

多机房

 

多机房一般有几种做法。

 

(1) 跨机房写。通过 DNS 解析将不同区域的⽤户分发到指定机房,流量上没有主从区别,但是从读写⻆度来看,机房已分为主从机房。假设有机房 1、机房 2 两个机房,机房 1 跨机房写会把机房分成主从模式,机房 1 接收读、写,机房 2 只负责读,它的写需要直接请求到主机房的数据库来进行。

 

这种做法适合读多写少的场景,例如用户中心、资讯内容服务等。跨机房写的优势是实现比较简单,在数据库层实现读写分离,业务只需要配置读写数据库链接就可实现多机房部署。

 

跨机房写的缺点是时延高,并且依赖机房之间专线的质量可靠性。

 

 

 

(2) 消息队列写。和跨机房写的架构很相似,只是在从机房写入的时候不是跨机房直接写入,而是先写⼊消息队列,再依靠消息队列将数据传输到主机房,写入都在本地完成。这一做法避免了跨机房的⽹络抖动带来的写入故障问题,同时也提升了系统在从机房的写入性能。主机房仍然是在逻辑层对消息队列的数据进行接收,再写⼊主机房的主数据库。由于写入采取了消息队列实现,所以这种模式可以适⽤于更广泛的场景,例如读多写少、读写均衡,以及对于数据及时性不敏感的写多读少业务,如本地生活、数据备份存储等。

 

以本地生活为例,假设一个用户一直在广东本地生活,数据不会出现频繁切换的情况,因此允许使用消息队列来进行传输,延迟一天关系也不大,数据可以做到高可用。

 

再以华南和华北两个不同地区的机房为例,华南机房可以先接纳华南地区用户的一些数据,华北机房的数据除了存储在华北机房,还需要备份到华南机房,但华北机房使用的数据仍然来自自身。这种同步降低了业务在实时链路中跨机房时延。

 

 

 

(3) 消息队列双向写。这种模式已经有双活的形态了,每个机房都可以独立地进行读写,本地通过数据库主从进行同步,本地有新增修改数据时都通过消息队列进行同步修改。双向写的模式主要适合本地写比较多的业务场景。消息队列双向写与用户切分紧密结合能够取得比较好的效果。

 

 

(4) 用户切分。正常访问场景下按照⽤户切分进行本地访问,并且引入数据库双向同步组件来进行数据同步,当其中⼀个机房出现故障的时候,直接将流量切换到另⼀个机房,并设置服务流量切换标志,接入层发现这个标志则不强制用户到指定机房,访问本地机房的数据库。由于在正常场景下用户的数据已实现同步,所以切换到另⼀个机房后也可以访问该用户的数据,不过数据同步的效率会使数据不⼀致问题短暂出现。这种架构模式比较适合数据备份、用户授权以及本地生活服务等场景。

 

 

 

以上是多机房中 4 个常见的读写方案。接下来我们通过一个账号授权系统案例来帮助大家进一步理解。

 

 

 

 

用微信/支付宝登录服务就是一个授权的过程,用户提交登录请求后,进行账密验证。系统也需要向用户申请授权,例如核心应用可以获取用户所有信息字段,一些生态应用可以申请获取用户昵称、头像等信息。授权过程中通过 token 加解密来认证和互通权限。这个过程包括用户的 token 生成、token 加密以及 token 同步。

 

 

 

基于多机房的场景,假设 token 同步过程出现了问题,应该如何做呢?从原则上来说,设计方案中需要有 token 同步功能,接下来就是缓存和数据库,缓存 token 加解密等信息,数据库对配置进行存储,这些共同构成了授权服务的框架。

 

授权服务相对来说是一个比较简单的服务。但多机房怎么实现呢?回到上述的多机房实现方案,一个比较好的做法就是将用户切分与消息同步结合。

 

 

 

整体方案是用异步的方式来进行数据同步,然后进行数据的主动拉取和自降级校验。一般情况下,对用户进行切分,机房 1 和机房 2 分别处理相应的用户请求,生成 token 进行校验。假设此时机房 1 出现了一些问题,就需要把流量切换到机房 2,此时在机房 1 中 token 也会解析写入,同步到机房 2。这个过程中存在时间差,可能在机房 1 出现问题后,流量切换到机房 2 时 token 还没有解析写入,此时应该怎么办呢?可以参考以下做法:

 

● 机房接⼊层出现故障:切换流量到另外⼀个机房,如果本地能够获取 token 则直接验证,如果没有则采取对内接⼊层提供的内部接⼝实时获取(机房间专线);

● 如果机房专线也出现问题:则采取降级⾃校验的模式,例如授权⽤户获取的 key 通过加密封装⼀些⽤户基本信息(uid/time/机房 tag/业务属性等),解密后⾃校验;

● Token 的多机房同步:除了业务直接写⼊消息队列⽅案,也可监听缓存的写⼊事件,并且解析⽇志再同步到对应机房。这里存在两个问题:(1) 多机房循环复制问题(可通过机房标识解决);(2) 监听消息性能有限,容易出现较⼤同步时延。

 

 

 

 

这次分享我们主要从高可用的一些实际事件引入,介绍了高可用的一些理论基础,接着对系统高可用分层实现方案做了详细的说明和介绍,最后对一个账号授权系统做了高可用架构设计的分析以及注意的问题。

更多产品了解

欢迎扫码加入云巴巴企业数字化交流服务群

产品交流、问题咨询、专业测评

都在这里!

 

热门数字化产品

Udesk 智能质检系统Udesk智能质检系统使用ASR语音识别技术、语义判定及规则匹配打造智能质检引擎,智能分析通话内容,挖掘对话中服务问题与商机.实现对客服工作的完全质检,充分把控客服通话质量,提高工作效率,降低运营风险和成本。
快书编标系统快书编标系统强大易用的专业编标工具,让零基础的人也可以快速上手,轻松完成标书制作。专属企业的编标机器人,企业内部资源共享,有序管理,形成私有且易于管理的企业资源库。快书编标帮助个人提升工作效率,帮助企业实现业绩持续增长,为社会创造更多价值。
销售易CRM销售易CRM,销售L2C全流程自动化管理,赢单更多更快。多维度目标管理,让制定的目标切实可行。智能区域管理,实现销售资源的高效分配。与ERP无缝集成,打通企业前后端业务流程。
上讯信息敏捷数据脱敏系统SDM敏捷数据管理平台软件(ADM)是上海上讯信息技术股份有限公司(以下简称“上讯信息”)自主研发的,主要面向金融、运营商、政府、能源、医疗等行业打造的全生命周期数据安全管理软件产品,用于数据备份、备份数据恢复验证、测试数据交付和静态数据脱敏等应用场景,可为企业上、中、下游数据的高效使用和安全管控提供一套整体解决方案。
携客云采购管理系统SRM携客云的每个应用功能都经过用户的千锤百炼,无论是大型的集团,或是快速成长的企业,都能够为您企业供应链每个管理环节,找到最佳的业务管理方案,并配置您所需要的管理流程和业务细节。
为你推荐
直播间在线人数卡在500上不去?天志互联抽盒系统从互动率破局

抖音算法推流核心指标是互动率而非GMV。天志互联直播抽盒系统从订单秒级上屏、一键拆盒、氛围引爆三个维度拉高互动率,驱动算法推流的正循环。

2026-06-26
品牌联名越做越亏?天志互联用游戏化体验共创重新定义IP营销

从"换皮联名"到"游戏化体验共创"——拆解彩棠敦煌联名案例的壁画修复小游戏设计逻辑、奶茶品牌联名翻车教训和中小品牌三条低成本高ROI的IP联名路径。

2026-06-26
一个人也能搭游戏化运营体系?低代码时代品牌运营的乐高式搭建指南

低代码时代品牌游戏化运营体系的"乐高式"搭建指南——从选模板、搭积分闭环、数据迭代到多活动并行管理和团队交接的全流程实操方法。

2026-06-26
私域社群打开率跌破3%以后:一个快消品牌的游戏化自救实验

一个快消品牌用游戏化方法三个月救活240个死群的完整复盘——从签到排行榜、互动任务、习惯养成到赛季制防疲劳的六周运营节奏拆解。

2026-06-26
品牌私域裂变怎么设计才不被骂?游戏化社交裂变的三个底线原则

游戏化社交裂变的三个底线原则深度拆解——让转发不像广告、让奖品有炫耀价值、给用户不转发的自由,加3%超级用户识别策略和三个常见翻车点避坑指南。

2026-06-26
查看更多