关于程序员:分布式系统如何保证高可用性下

40次阅读

共计 2818 个字符,预计需要花费 8 分钟才能阅读完成。

限流设计
熔断设计爱护的是服务调用者,即上游服务的可用性,对于上游服务提供者,思考到本身服务实例的负载能力,同样须要限流设计爱护本人不被适量的流量冲垮。一般来讲有以下的限流策略:

拒绝服务,把多进去的申请回绝掉。一般来说,好的限流零碎在受到流量暴增时,会临时回绝周期时间内申请数量最大的客户端,这样能够在肯定水平上把一些不失常的或者是带有歹意的高并发拜访挡在门外。
服务降级,敞开或是把后端做降级解决,开释资源给撑持主流程服务以反对更多的申请。降级有很多形式,一种是把一些不重要的服务给停掉,把 CPU、内存或是数据的资源让给更重要的性能;一种是数据接口只返回局部要害数据,缩小数据查询处理链路;还有更快的一种是间接返回预设的缓存或者静态数据,就义数据强一致性的形式来取得更大的性能吞吐。
优先级申请,是指将目前零碎的资源分配给优先级更高的用户,优先解决权限更高的用户的申请。
延时解决,在这种状况下,一般来说会应用缓冲队列来缓冲大量的申请,零碎依据本身负载能力生产队列中的申请。如果该队列也满了,那么就只能回绝用户申请。应用缓冲队列只是为了减缓压力,个别用于应答刹时大量的流量削峰。
弹性伸缩,采纳自动化运维的形式对相应的服务做自动化的伸缩。这种计划须要利用性能监控零碎,可能感知到目前最忙碌的服务,并主动伸缩它们;还须要一个疾速响应的自动化公布、部署和服务注册的运维零碎。如果零碎的解决压力集中在数据库这类不易主动扩容的内部服务,服务弹性伸缩意义不大。
接下来咱们介绍两种罕用的限流算法:漏桶算法和令牌桶算法。

漏桶算法 (Leaky Bucket) 是网络世界中流量整形 (Traffic Shaping) 或速率限度 (Rate Limiting) 时常常应用的一种算法,它的次要目标是控制数据注入到零碎的速率,平滑对系统的突发流量,为零碎提供一个稳固的申请流量。

如上图所示,水 (申请) 先进入到漏桶,而进来的水量示意零碎解决的申请。当拜访流量过大时漏桶中就会积水,如果水太多了就会溢出,此时申请将会被回绝。

令牌桶算法则是一个寄存固定容量令牌的桶,依照固定速率往桶里增加令牌。桶中寄存的令牌数有最大下限,超出之后就被抛弃。当流量或者网络申请达到时,每个申请都要获取一个令牌,如果可能获取到,则间接解决,同时令牌桶会删除一个令牌。如果获取不到,该申请就要被限流,要么间接抛弃,要么在缓冲区期待。

其余设计与计划
降级设计
在应答大流量冲击时,能够尝试对申请的解决流程进行裁剪,去除或者异步化非关键流程的主要性能,保障主流程性能失常运行。

一般来说,咱们的降级时能够临时就义的货色有:

升高一致性。从数据强一致性变成最终一致性。
敞开非关键服务。敞开不重要性能的服务,从而开释出更多的资源。
简化性能。把一些性能简化掉,比方,简化业务流程,或是不再返回全量数据,只返回局部数据。也能够应用缓存的形式,返回预设的缓存数据或者静态数据,不执行具体的业务数据查询处理。
无状态设计
在分布式系统设计中,都提倡应用无状态化的形式设计开发服务模块。无状态的意思是指对于性能雷同的服务模块,在服务外部不保护任何的数据状态,只会依据申请中携带的业务数据从内部服务比方数据库、分布式缓存中查问相干数据进行解决,这样可能保障申请到任意服务实例中处理结果都是统一的。

无状态设计的服务模块能够简略通过多实例部署的形式进行横向扩大,各服务实例齐全对等,能够无效进步服务集群的吞吐量和可用性。然而如此一来,服务解决的性能瓶颈就可能呈现在提供数据状态一致性的内部服务中。

幂等性设计
幂等性设计是指零碎对于雷同的申请,一次和屡次申请获取到的后果都是一样的。幂等性设计对分布式系统中的超时重试、零碎复原有重要的意义,它可能保障反复调用不会产生谬误,保证系统的可用性。个别咱们认为申明为幂等性的接口或者服务呈现调用失败是常态,因为幂等性的起因,调用方能够在调用失败后释怀进行从新申请。举个简略的例子,在领取零碎中,在一笔订单的领取申请中,因为网络抖动或者其余未知的因素导致申请没能及时返回,如果领取接口是幂等性,咱们应该能够放心使用同一笔订单号从新申请领取,如果上次领取申请曾经胜利,将会返回领取胜利,如果上次领取申请未胜利,将会从新进行金额扣费,这样就能保障申请的正确进行,防止反复扣费的谬误。

重试设计
在很多时候,因为网络不牢靠或者服务提供方宕机的起因,服务调用者的调用很可能会失败,如果此时服务调用者中存在肯定的重试机制,就可能在肯定水平上缩小服务失败的概率,进步服务可用性。比方业务零碎在某次数据库申请中,因为长期的网络起因,数据申请超时了,如果业务零碎中具备肯定的超时重试机制,依据申请参数再次向数据库申请数据,就能失常获取到数据,实现业务解决流程,防止该次业务解决失败。

应用重试设计的时候须要留神以下问题:一是待重试的服务接口是否为幂等性,对于某些超时申请,申请可能在服务提供方中执行胜利了,然而返回后果在网络传输中失落了,此时反复调用非幂等性服务接口很可能会导致额定的零碎谬误;二是服务提供方是否只是长期不可用,对于无奈疾速复原的服务提供方或者网络无奈立刻复原的状况下,自觉的重试只会使状况更加蹩脚,无脑地耗费服务调用方的 CPU、线程和网络 IO 资源,在这种状况下倡议联合熔断设计对服务调用方进行爱护。

接口缓存
接口缓存是应答大并发量申请,进步零碎吞吐量,保证系统可用性的无效伎俩。基本原理是,在零碎外部,对于某局部申请参数和申请门路实现雷同的申请的后果进行缓存,在周期时间内,这部分雷同的申请的后果将会间接从缓存中读取,缩小业务处理过程的负载。最简略的例子是在一些在线大数据查问零碎中,查问零碎会将周期时间内零碎查问条件雷同的查问后果进行缓存,放慢访问速度。

接口缓存同样有着它不实用的场景。接口缓存就义了数据的强一致性,对于实时性要求高的零碎并不实用。接口缓存放慢的是雷同申请的申请速率,对于申请差异化较大的零碎同样无能为力,过多的缓存反而会大量节约零碎内存等资源。

实时监控和度量
因为分布式中服务节点泛滥,问题的定位变得异样简单,对此倡议对每台服务器资源应用状况和服务实例的性能指标进行实时监控和度量。最常见的形式健康检查,通过定时调用服务提供给健康检查接口判断服务是否可用。目前业内也有开源的监控零碎 Prometheus,它监控各个服务实例的运行指标,并依据预设的阀值主动报警,及时告诉相干开发运维人员进行解决。

常布局化保护
定期清理零碎的无用代码,及时进行代码评审,解决代码中 bad smell。对于无状态服务能够定期重启服务器缩小内存碎片和避免内存透露。这些都是十分无效的进步零碎可用性的运维伎俩。

总结
尽管在分布式系统中,因为零碎的复杂性,大大加大了服务谬误的可能性,然而也有足够的计划保证系统可用性。本文首先介绍了零碎可用性指标,接着论述了分布式系统中故障不可避免的状况,最初抽象地介绍了一些无效的高可用设计。

正文完
 0