架构设计系列文章,请参见连接。
背景
在分布式软件系统中解决可靠性问题可以分为两个方向:主动预防故障发生,防止故障在系统中扩散。现阶段大部分关于分布式系统的可靠性方面的研究还是集中在怎样阻止故障发生,以预防故障的发生而提高系统的可用性。现在互联网行业中逐渐的发展壮大,也伴随着互联网软件的体系的故断壮大。在不断壮大的软件系统中,故障成为不可避免的事情。而在发生故障时怎样控制故障范围最小就成为现阶段要管理的问题。
在这个过程中有几个关键概念需要献说明以下:
故障隔离
故障隔离指的是在航空器上实时工作环境下,对系统或设备的分系统各部分分别判定其正常工作状态,缩小到最后判定有故障的分系统或部分的技术措施。连锁故障
连锁故障指由于电力系统电气量间的相互关联,当某一故障发生时随之引发的其他故障。故障树分析法
其实这个概念是为了说明故障传播的概念。
故障树分析(FTA)一开始是由贝尔实验室的H.A.Watson所发展的,一开始是因为美国空军第526 ICBM系统群的委托,要评估义勇兵一型洲际弹道导弹(ICBM)的发射控制系统。之后故障树分析开始成为可靠度分析者进行失效分析的工具。根因分析
根本原因分析(RCA)是一项结构化的问题处理法,用以逐步找出问题的根本原因并加以解决, 而不是仅仅关注问题的表征。
故障传播方式
在解决故障传播的问题时,确定故障传播的方式是确定问题原因的一种方式。这里是对与作者现阶段认识到的故障传播方式。主要可以分为:惊群效应,同质化问题,资源共享。
- 惊群效应
以下内容是《SRE》中关于连锁故障的描述:连锁故障是由于正反馈循环(positive feedback)导致的不断扩大规模的故障。连锁故障可能由于整个系统的一小部分出现故障而引发,进而导致系统其他部分也出现故障。例如,某个服务的一个实例由于过载出现故障,导致其他实例负载升高,从而导致这些实例像多米诺骨牌一样一个以全部出现故障。
假设前端服务器在集群A中正在处理1000QPS的请求。如果集群B出现故障,发往集群A的请求上升至1200QPS。集群A中的前端服务无法处理这么多请求,由于资源不够等原因导致崩溃、超时,或者出现其他异常情况。结果,集群A成功处理的的请求远地域之前的1000QPS。
- 同质化问题
之前看过一种理论,同一个磁盘阵列中不能购买同一品牌,同一批次的磁盘组成磁盘阵列。原因是:从理论上来说,同一批次,又是同一使用环境,一起出问题的概率总要比不同批次的概率大点。
也就是在相似的初始条件下,又进行了相似的器件损耗的。造成同样问题的可能性也比较高。将这个问题推广到我们的软件系统中,会发现问题更加严重。因为我们的软件系统中服务都是同一个服务多实例部署的,这样就会发现服务不是相似的那么简单的了,服务是一样的。那么推导下去多实例中每一个服务对于同一件事情的处理方式,响应方式都是一样的。那么一个服务遇到一个错误,这类错误就会发生在所有的实例上。
- 资源共享
以下内容是《架构即未来》中关于故障隔离架构的描述:在我们的实践中,经常吧故障隔离架构比喻成泳道(Swim lane)。我们相信这个比喻生动地描述了希望在故障隔离中实现的画面。对于游泳选手,泳道既代表了故障也代表了引导。障碍物的存在是为了确保游泳选手产生的波浪不进入另一个泳道,干扰其他游泳选手。在比赛中,这有助于确保选手不受干扰,避免不恰当地影响每个游泳选手赢得比赛的概率。
现在都在使用微服务进行服务的业务的管理与调度工作。对于服务来说服务的共享资源就成为不同业务抢占的资源,例如CPU资源,内存资源,数据库连接资源,线程资源,文件描述符资源等等。简单的说就是如果一个业务处理时间较长或卡住那么整体业务就可能被卡住,导致系统假死问题。
故障传播检测
系统监控就是为了实时的了解系统的运行状态而建设的。那针对故障传播的监控或着感知系统现阶段还是很少的,基本上没有搜索到相关的资料信息。对于在故障传播过程中去检测都是需要加入智能运维的内容。通过智能运维的各项指标监控输入,然后通过AI系统的判断形成故障传播告警。
除了故障发生传播过程中需要感知故障传播,还有就是在验证环境中对故障传播模型或者根本原因分析进行相关的工作。在这个过程中可以使用预生产环境中进行实践工作。使用连锁故障测试的方式对业务故障的扩散进行发现与管理工作。
- tcpcopy
使用tcpcopy进行线上流量copy到预生产环境中进行线上流量的测试。 - 故障注入
使用故障注入的方式故障传播方式的研究工作。 - 混沌工程
混沌工程就是随机的注入问题。 - 数据可视化
线上环境上对于调用链的展示,以及对于系统指标中的可视化展示需要可以一眼看到是否发生故障。发生了故障之后直接看到故障点在哪里。
故障传播解决
现阶段大部分系统都忽略了故障传播问题的解决,所以,作者见到的系统中绝大部分故障都是因为传播的问题而导致系统整体瘫痪的。几乎所有的故障都会传播到整个系统中形成系统整体瘫痪的问题,这个就是系统不稳定的问题。使用方法论引导解决方案的思路进行落地工作。
原则
- 减少共享
其实严格来说故障隔离是不允许共享的。他的思路是即然是一个隔离的组件,那么这个组件应该包括所有的依赖项,在没有其他组件的情况下自身可以运行的。甚至说都不需要通讯。但是,实际开发中是没有绝对的隔绝的,一些系统特别是核心系统是需要沟通的。所以我们建议是减少共享。如果需要共享,最好是用解耦合的方式共享。例如:消息队列的方式和其他的组件或者系统进行通信。这样既保证了通讯也保证了系统的独立性不受影响。 - 不跨越系统边界
就如上面提到的系统边界就好像泳道一样,系统是不能跨越边界到达其他系统的。如果需要通讯需要,按照第一条中提到的通过中间件的方式来完成。为什么在这里要特别提出来,是因为被放在隔离区域中的系统通常都针对特定的客户,特定的业务,特定的组件。如果他们和外界的系统有过多的交集,就明显无法达到隔离的效果。 - 所有的交易只能发生在系统边界内
实际上需要完成的是,所有的交易闭环都在系统边界内完成,交易中的任何环节都不要出现在系统之外。举几个例子:和利益相关的业务,经常出现故障的业务,用户边界明显的业务。
- 减少共享
故障解决方法
- 资源隔离
对于抢夺资源造成服务内,服务间的故障传播还是故障传播的原因。所以需要对线程池隔离,数据库连接池隔离,消息通道隔离等都需要进行管理。 - 服务降级
现在对于微服务中的一个服务中,对于接口降级还是对于服务降级是需要有固定的定义的。因为小范围故障的时候可能是某个接口在线上返回时间超长,卡顿的问题。需要可以进行故障降级的业务关联性的内容。 - 服务容错
在其他服务发生错误时需要进行友好的错误回复,并在调用需要进行业务过程的管理定义在业务流程中哪些业务流程是可以忽略的,哪些是必须要的。怎样通过BASE的问题进行管理。 - 间接依赖
访问中间服务,而不是直接访问对方服务。尽量减少直接耦合。(rpc就是直接耦合的一个特例)
- 资源隔离
技术解决方案
上面已经说明了上层理论,并以上层理论进行了具体可落地方向的划分工作。落地方向定义了之后,这里定义这些落地方向下现在可行的一些技术解决方案内容。
资源隔离
Hystrix线程隔离技术解析-线程池
数据库连接池隔离现阶段没有成熟的解决方案。服务降级
sentinel的限流与服务降级的功能。
热点隔离抢购、秒杀、开门红等业务,都属于热点。对于这种系统,应该造成独立的系统进行隔离,底层使用配置较高的硬件服务器、更好的网络带宽,并且加入多级缓存。
服务容错
特性开关相关的功能。
Togglz,FF4J,Fitchy,Flip可视化
总结
需要可以进行运维知识图谱才能真正的理解关于故障隔离的内容。之后可能根据这个专题进行相关的细化分析工作。并进行
现阶段对于故障隔离的检测,没有很好的方法进行。只能通过我们每个从业者进行不断的探索形成业界解决方案才能逐渐的解决我们在故障管理,故障传播中的管理工作。
这里不说像《互联网架构中的9种隔离术以及容器化的实现》不同资源的隔离方式。这里从为什么需要故障隔离,故障隔离发生后怎样检查,检测到了故障传播之后怎样解决。
参考
故障传播模型
多因素集成的分布式应用故障诊断方法
一种面向故障隔离的测试向量优化方法
《SRE-Google运维解密》的第22章处理连锁故障
《架构即未来》为什么架构师一定要懂“故障隔离”?业内专家一语点破!故障检测
故障检测和隔离