高可用系统常用解决手段浅述

2024-05-02 03:32

本文主要是介绍高可用系统常用解决手段浅述,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

所谓可用性,是指某系统能够提供正常服务的特性。

可用性的高低是使用不可用时间总时间的比例来衡量。不可用时间是从故障发生到故障恢复的时间。比如,可用性4个9的系统(99.99%),它一年宕机时间不能超过53分钟(=365*24*60*(1-0.9999))。做到高可用系统,需要尽可能的减少故障发生次数缩短故障持续时间

系统可用性%宕机时间/年宕机时间/月宕机时间/周宕机时间/天
90% (1个9)36.5 天72 小时16.8 小时2.4 小时
99% (2个9)3.65 天7.20 小时1.68 小时14.4 分
99.9% (3个9)8.76 小时43.8 分10.1 分钟1.44 分
99.99% (4个9)52.56 分4.38 分1.01 分钟8.66 秒
99.999% (5个9)5.26 分25.9 秒6.05 秒0.87 秒

出现系统不可用的原因,一种是人为的,比如发布了有bug的代码、不规范的发布流程导致的宕机,或者网站访问量过载造成的雪崩等;另一种则是非人为的,由于外部系统和环境的变化造成的,比如硬盘故障、机房断电、电缆中断等。我们需要在复杂的外部环境下保证系统的高可用。以下总结了常用的高可用解决手段。

1.拆分

这类解决手段不是以减少不可用时间为目的,而是以缩小故障影响面为目的。因为一个大的系统拆分成了几个小的独立模块,一个模块出了问题不会影响到其他的模块,从而缩小故障的影响面。手段包括:

1.1 水平拆分

系统水平拆分成三层:接入层,服务层和数据存储层。将有状态和无状态的划分开来,接入层和服务层设计成无状态的,存储层是有状态的。无状态层的服务可以平行扩展,请求落到哪台服务器都没有关系。平行扩展也有利于系统容量的扩充,快速扩容应对突然爆发流量的冲击。

1.2 垂直拆分

根据功能垂直划分,拆成相对独立的模块。有的仅是服务层做了拆分,存储层共用。更为彻底的是,拆分与该系统的业务领域模型关联,一个领域模型划分成一个模块。在数据库层面,还可以分库分表拆分,这样一个库的损坏,不会影响到其他库。分库分表需要增加路由逻辑,及保证路由规则的一致性。

1.3 读写分离

也属于垂直拆分的一种。写请求的依赖主库,读请求的依赖备库。这样做,当出现故障的时候,可以只有读请求的流量,写服务暂时关闭,从而减少了故障的影响面。但需要关注数据一致性的问题。

2.降级

这类手段不是为了防止故障的发生,而是当故障发生后,怎么减小故障所造成的损失。比如,系统正常时提供的服务能力是100%,出现系统故障后,我们有措施能让系统服务能力不直接降到了0,而是还能提供部分(比如50%)的服务能力。

2.1 限流

限流,流量控制。当请求量超过系统的最大容量后,访问延迟就会增加,超过峰值的流量会拖累整个系统,出现宕机。因此,需要提前流量控制,对于超过峰值的流量,可以直接拒绝掉或者选择随机拒绝。限流结合业务自定义配置优先保证核心服务的正常响应,非核心服务可直接关闭。

2.2 异步调用

系统进行拆分之后,会分成多个模块。模块之间的依赖有强弱之分。如果是强依赖的,那么如果依赖方出问题了,也会受到牵连出问题。这时可以梳理整个流程的调用关系,做成弱依赖调用。弱依赖调用通过消息中间件的方式来实现

异步调用不关心返回结果,不会传递依赖方的错误,进而避免造成更大规模的不可用。

 

2.3 同步调用合理设置超时时间

对于不能异步化的,采用同步调用,需要注意设置合理的超时时间。过长的超时,会延迟结果等待时间,导致整体的链路调用时间延长,降低整体的QPS。

经验值:超时时间设置成平均响应延迟的2倍

2.4 失败重试

要区分调用失败的类型。有些失败是短暂偶然的(比如网络抖动),进行重试即可。而有些失败是确定,那么重试反而会造成调用请求量的放大,加重对调用系统的负担。

经验值:重试的次数一般设为3次,再多次的重试没有好处。

2.5 兜底方案

在系统真的出现了不可用的时候,需要有兜底方案。比如一些提示安抚用户,或者设置跳转链接以转移用户的请求。

3.冗余

冗余,目的是避免单点故障。比如对于接入层和服务层,可以平行扩展机器部署,这样一台机器宕机,可以将请求转移到其他机器。数据层的冗余比较复杂,增加一份备份数据,需要考虑一致性的问题。按照分布式系统的CAP理论三者不可用同时满足的原理,为了满足可用性和分区容错性,就必须牺牲一致性,因此考虑使用弱一致性、最终一致性的解决方案来解决(此类文章很多,略)。

冗余备份有全量和增量之分,有热备和冷备之分。冗余可以是两台机器的主备冗余,可以是多机的集群式冗余。从部署来看,可以是跨机架、跨机房到跨城的备份。多机复制部署,上层调用采用负载均衡策略,还需要注意负载均衡设备的单点问题。

失败通知和失败切换

当集群机器某台机器出现了故障,或者某个进程挂了,能够快速的发现,并且告警通知出来。路由选择器能快速的切除掉这台机器,当恢复后又能自动的加入回来。

4.灰度发布

有个观点,单点发布是可用性最大的敌人。线网出现了故障,查故障的原因,一个常用的办法就是追查下最近是否有发过版本,比较下发布前后的代码。

使用灰度发布策略,发布并且验证没问题后再全量发布。灰度发布的策略,包括搭建预发布环境,有专用的预发布机器;或者路由策略先摘除灰度发布的机器,验证正常后再加入该机器;或者采用UIN取模灰度策略,验证没问题后再取消灰度策略。尽量采用自动化发布,减少人为发布的流程。尽量选择在访问量低峰时段升级,减小影响用户群。

回滚机制

出现问题后,能有有效的回滚机制。涉及到数据修改的,发布后会引起脏数据的写入,需要有可靠的回滚流程,保证脏数据的清除。

除了发布流程外,还应该在其他开发流程上做规范,比如代码控制,集成编译、自动化测试、静态代码扫描等。

5.切换

切换之前需要做好监控。监控应该是贯穿于上述所有手段的。比如业务某个模块访问量要监控,依赖的调用方出问题要监控,某个机房故障了要监控,发布了服务要监控等。监控既包括系统层面的(比如CPU、内存、网络、IO、进程),还包括业务层面的(请求量、错误率、耗时)。监控的间隔需要支持到分钟级甚至到秒级的。

监控不是目的,监控没法保证高可用,切换才是目的,从故障的系统切换到正常的系统才能保证可用性。比如监控到某台机器的硬盘出问题了,那么告警要出来,然后使用一台新的机器替换。切换可以是自动的,也可以是人工的。人工切换会有延迟恢复的问题,但能做到准确。自动切换,会比较快速,但必须要确保切换源是正常的,否则可能会引起更加严重的事故。切换后,要有实时的效果反馈。

最后

高可用手段远不止本文所述的。本文只具有理论指导意义,实际实现高可用的系统,需要结合实际业务场景和所使用的开发框架来完成。

手段方式内容补充
拆分水平拆分将系统水平拆分为:接入层,服务层和数据存储层。将有状态和无状态的区分开,接入层和服务层设计成无状态,存储层是有状态的。
垂直拆分根据功能垂直划分,拆成相对独立的模块。可以仅对服务层进行拆分,存储层共用;在数据库层面分库分表(需增加路由逻辑,保证路由规则一致性)。
读写分离,写请求的依赖主库,读请求的依赖备库。需要关注数据一致性问题。
降级请求限流限流,流量控制。请求的增加会导致访问延迟增加,超过峰值会拖垮整个系统,对超过负载的流量应选择直接/随机拒绝。
异步调用强依赖会导致牵连;弱依赖则不会。弱依赖通过消息中间件的方式来实现。异步调用不关心返回结果,不会传递依赖方的错误,可避免更大规模的不可用。
超时设置对于不能异步化的,只能采取同步调用,那么就需要设置合理超时时间。同步调用的超时时间设置成平均响应延迟的2倍。
失败重试失败重试是必要的,但有些场景的失败重试反而会加重被调用方的负担。重试的次数一般设为3次,再多次的重试没有好处。
兜底方案确实不可用时,应设置跳转链接以转移用户的请求,以提示安抚用户。提高客户体验。
冗余冗余备份冗余的目的是避免单点故障;备份有全量和增量之分,有热备和冷备之分。数据层的冗余会带来一致性问题,为满足可用性和分区容错性,需要考虑弱一致性、最终一致性的解决办法。
发布灰度发布使用灰度发布策略,发布并且验证没问题后再全量发布。配备回滚机制,出现问题后,能有有效的回滚机制。
监控全程监控监控应该是贯穿于上述所有手段的。监控不是目的,监控没法保证高可用,切换才是目的。

这篇关于高可用系统常用解决手段浅述的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/953300

相关文章

2024.6.24 IDEA中文乱码问题(服务器 控制台 TOMcat)实测已解决

1.问题产生原因: 1.文件编码不一致:如果文件的编码方式与IDEA设置的编码方式不一致,就会产生乱码。确保文件和IDEA使用相同的编码,通常是UTF-8。2.IDEA设置问题:检查IDEA的全局编码设置和项目编码设置是否正确。3.终端或控制台编码问题:如果你在终端或控制台看到乱码,可能是终端的编码设置问题。确保终端使用的是支持你的文件的编码方式。 2.解决方案: 1.File -> S

通信系统网络架构_2.广域网网络架构

1.概述          通俗来讲,广域网是将分布于相比局域网络更广区域的计算机设备联接起来的网络。广域网由通信子网于资源子网组成。通信子网可以利用公用分组交换网、卫星通信网和无线分组交换网构建,将分布在不同地区的局域网或计算机系统互连起来,实现资源子网的共享。 2.网络组成          广域网属于多级网络,通常由骨干网、分布网、接入网组成。在网络规模较小时,可仅由骨干网和接入网组成

Eureka高可用注册中心registered-replicas没有分布式注册中心

自己在学习过程中发现,如果Eureka挂掉了,其他的Client就跑不起来了,那既然是商业项目,还是要处理好这个问题,所以决定用《Spring Cloud微服务实战》(PDF版在全栈技术交流群中自行获取)中说的“高可用注册中心”。 一开始我yml的配置是这样的 server:port: 8761eureka:instance:hostname: 127.0.0.1client:fetch-r

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在

vue+elementui分页输入框回车与页面中@keyup.enter事件冲突解决

解决这个问题的思路只要判断事件源是哪个就好。el分页的回车触发事件是在按下时,抬起并不会再触发。而keyup.enter事件是在抬起时触发。 so,找不到分页的回车事件那就拿keyup.enter事件搞事情。只要判断这个抬起事件的$event中的锚点样式判断不等于分页特有的样式就可以了 @keyup.enter="allKeyup($event)" //页面上的//js中allKeyup(e

vue+elementui--$message提示框被dialog遮罩层挡住问题解决

最近碰到一个先执行this.$message提示内容,然后接着弹出dialog带遮罩层弹框。那么问题来了,message提示框会默认被dialog遮罩层挡住,现在就是要解决这个问题。 由于都是弹框,问题肯定是出在z-index比重问题。由于用$message方式是写在js中而不是写在html中所以不是很好直接去改样式。 不过好在message组件中提供了customClass 属性,我们可以利用

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

Pycharm配置conda环境(解决新版本无法识别可执行文件问题)

引言: 很多小伙伴在下载最新版本的pycharm或者更新到最新版本后为项目配置conda环境的时候,发现文件夹目录中无法显示可执行文件(一般为python.exe),以下就是本人遇到该问题后试验和解决该问题的一些方法和思路。 一般遇到该问题的人群有两种,一种是刚入门对pycharm进行conda环境配置的小白(例如我),不熟悉相关环境配置的操作和过程,还有一种是入坑pycharm有段时间的老手

青龙面板之Ninja无法安装无法拉库问题解决

因为之前的Ninja库已经不能用了,甚至新找到的库也不能用了,好尴尬,这里使用线下版本进行安装。 ninja安装新方法,其是方法还是原来的,只不过Ninja的库原作者删了,没法直接git了,但是我找到了源码包,我们可以直接通过宝塔面板拖进去。 源码包地址: https://download.csdn.net/download/u012134073/24813485 备用地址: 链接: h