一、前言
高并发、高可用、高性能被称为互联网三高架构,这三者都是工程师和架构师在零碎架构设计中必须思考的因素之一。明天咱们就来聊一聊三 H 中的高可用,也是咱们常说的零碎稳定性。
本篇文章只聊思路,没有太多的深刻细节。浏览全文大略须要 5~10 分钟。
二、高可用的定义
业界罕用 N 个 9 来量化一个零碎可用性水平,能够间接映射到网站失常运行工夫的百分比上。
可用性的计算公式:
大部分公司的要求是 4 个 9,也就是年度宕机时长不能超过 53 分钟,理论要达到这个指标还是十分艰难的,须要各个子模块相互配合。
要想晋升一个零碎的可用性,首先须要晓得影响零碎稳定性的因素有哪些。
三、影响稳定性的因素
首先咱们先梳理一下影响零碎稳定性的一些常见的问题场景,大抵可分为三类:
- 人为因素
不合理的变更、内部攻打等等 - 软件因素
代码 bug、设计破绽、GC 问题、线程池异样、上下游异样 - 硬件因素
网络故障、机器故障等
上面就是隔靴搔痒,首先是故障前的预防,其次是故障后的疾速恢复能力,上面咱们就聊聊几种常见的解决思路。
四、晋升稳定性的几种思路
4.1 零碎拆分
拆分不是以缩小不可用工夫为目标,而是以缩小故障影响面为目标。因为一个大的零碎拆分成了几个小的独立模块,一个模块出了问题不会影响到其余的模块,从而升高故障的影响面。零碎拆分又包含接入层拆分、服务拆分、数据库拆分。
- 接入层 & 服务层
个别是依照业务模块、重要水平、变更频次等维度拆分。 - 数据层
个别先依照业务拆分后,如果有须要还能够做垂直拆分也就是数据分片、读写拆散、数据冷热拆散等。
4.2 解耦
零碎进行拆分之后,会分成多个模块。模块之间的依赖有强弱之分。如果是强依赖的,那么如果依赖方出问题了,也会受到牵连出问题。这时能够梳理整个流程的调用关系,做成弱依赖调用。弱依赖调用能够用 MQ 的形式来实现解耦。即便上游呈现问题,也不会影响以后模块。
4.3 技术选型
能够在适用性、优缺点、产品口碑、社区活跃度、实战案例、扩展性等多个方面进行全量评估,挑选出适宜以后业务场景的中间件 & 数据库。后期的调研肯定要充沛,先比照、测试、钻研,再决定,磨刀不误砍柴工。
4.4 冗余部署 & 故障主动转移
服务层的冗余部署很好了解,一个服务部署多个节点,有了冗余之后还不够,每次呈现故障须要人工染指复原势必会减少零碎的不可服务工夫。所以,又往往是通过“主动故障转移”来实现零碎的高可用。即某个节点宕机后须要能主动摘除上游流量,这些能力基本上都能够通过负载平衡的探活机制来实现。
波及到数据层就比较复杂了,然而个别都有成熟的计划能够做参考。个别分为一主一从、一主多从、多主多从。不过大抵的原理都是 数据同步实现多从,数据分片实现多主 ,故障转移时都是 通过选举算法选出新的主节点 后在对外提供服务(这里如果写入的时候不做强统一同步,故障转移时会失落一部分数据)。具体能够参考 Redis Cluster、ZK、Kafka 等集群架构。
4.5 容量评估
在零碎上线前须要对整个服务用到的机器、DB、cache 都要做容量评估,机器容量的容量能够采纳以下形式评估:
- 明确预期流量指标 -QPS;
- 明确可承受的时延和平安水位指标(比方 CPU%≤40%,外围链路 RT≤50ms);
- 通过压测评估单机在平安水位以下能反对的最高 QPS(倡议通过混合场景来验证,比方依照预估流量配比同时压测多个外围接口);
- 最初就能够估算出具体的机器数量了。
DB 和 cache 评估除了 QPS 之外还须要评估数据量,办法大致相同,等到零碎上线后就能够依据监控指标做扩缩容了。
4.6 服务疾速扩容能力 & 泄洪能力
现阶段不论是容器还是 ECS,单纯的节点复制扩容是很容易的,扩容的重点须要评估的是服务自身是不是无状态的,比方:
- 上游 DB 的连贯数最多反对以后服务扩容几台?
- 扩容后缓存是否须要预热?
- 放量策略
这些因素都是须要提前做好筹备,整顿出齐备的 SOP 文档,当然最好的形式是进行演练,实际上手操作,有恃无恐。
泄洪能力个别是指冗余部署的状况下,抉择几个节点作为备用节点,平时承当很小一部分流量,当流量洪峰来长期,通过调整流量路由策略把热节点的一部分流量转移到备用节点上。
比照扩容计划这种老本绝对较高,然而益处就是 响应快,危险小。
4.7 流量整形 & 熔断降级
流量整形也就是常说的限流,次要是避免超过预期外的流量把服务打垮,熔断则是为了本身组件或者依赖上游故障时,能够疾速失败避免长期阻塞导致雪崩。对于限流熔断的能力,开源组件 Sentinel 基本上都具备了,用起来也很简略不便,然而有一些点须要留神。
- 限流阈值个别是配置为服务的某个资源能撑持的最高水位,这个须要通过压测摸底来评估。随着零碎的迭代,这个值可能是须要继续调整的。如果配置的过高,会导致系统解体时还没触发爱护,配置的过低会导致误伤。
- 熔断降级 - 某个接口或者某个资源熔断后,要依据业务场景跟熔断资源的重要水平来评估应该抛出异样还是返回一个兜底后果。比方下单场景如果扣减库存接口产生熔断,因为扣减库存在下单接口是必要条件,所以熔断后只能抛出异样让整个链路失败回滚,如果是获取商品评论相干的接口产生熔断,那么能够抉择返回一个空,不影响整个链路。
4.8 资源隔离
如果一个服务的多个上游同时呈现阻塞,单个上游接口始终达不到熔断规范(比方异样比例跟慢申请比例没达到阈值),那么将会导致整个服务的吞吐量降落和更多的线程数占用,极其状况下甚至导致线程池耗尽。引入资源隔离后,能够限度单个上游接口可应用的最大线程资源,确保在未熔断前尽可能小的影响整个服务的吞吐量。
说到隔离机制,这里能够扩大说一下,因为每个接口的流量跟 RT 都不一样,很难去设置一个比拟正当的可用最大线程数,并且随着业务迭代,这个阈值也难以保护。这里能够采纳共享加独占来解决这个问题,每个接口有本人的独占线程资源,当独占资源占满后,应用共享资源,共享池在达到肯定水位后,强制应用独占资源,排队期待。这种机制长处比拟显著就是能够在资源利用最大化的同时保障隔离性。
这里的线程数只是资源的一种,资源也能够是连接数、内存等等。
4.9 系统性爱护
系统性爱护是一种无差别限流,一句话概念就是在零碎快要解体之前对所有流量入口进行无差别限流,当零碎复原到衰弱水位后进行限流。具体一点就是联合利用的 Load、总体均匀 RT、入口 QPS 和线程数等几个维度的监控指标,让零碎的入口流量和零碎的负载达到一个均衡,让零碎尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
4.10 可观测性 & 告警
当零碎呈现故障时,咱们首先需找到故障的起因,而后才是解决问题,最初让零碎复原。排障的速度很大水平上决定了整个故障复原的时长,而可观测性的最大价值在于疾速排障。其次基于 Metrics、Traces、Logs 三大支柱配置告警规定,能够提前发现零碎可能存在的危险 & 问题,防止故障的产生。
4.11 变更流程三板斧
变更是可用性最大的敌人,99% 的故障都是来自于变更,可能是配置变更,代码变更,机器变更等等。那么如何缩小变更带来的故障呢?
- 可灰度
用小比例的一部分流量来验证变更后的内容,减小影响用户群。 - 可回滚
呈现问题后,能有无效的回滚机制。波及到数据批改的,公布后会引起脏数据的写入,须要有牢靠的回滚流程,保障脏数据的革除。 - 可观测
通过观察变更前后的指标变动,很大水平上能够提前发现问题。
除了以上三板斧外,还应该在其余开发流程上做标准,比方代码管制,集成编译、自动化测试、动态代码扫描等。
五、总结
对于一个动静演进的零碎而言,咱们没有方法将故障产生的概率降为 0,能做的只有尽可能的预防和缩短故障时的复原工夫。当然咱们也不必一味的谋求可用性,毕竟晋升稳定性的同时,保护老本、机器老本等也会跟着上涨,所以须要联合零碎的业务 SLO 要求,适宜的才是最好的。
如何做好稳定性和高可用保障是一个很宏大的命题,本篇文章没有太多的深刻细节,只聊了整体的一些思路,次要是为了大家在当前的零碎高可用建设过程中,有一套零碎的框架能够参考。最初感激急躁看完的同学。
* 文 / 新一
关注得物技术,每周一三五晚 18:30 更新技术干货
要是感觉文章对你有帮忙的话,欢送评论转发点赞~