当前位置: 首页 > 科技观察

Designforfailure

时间:2023-03-17 00:09:32 科技观察

中的12种常见设计思路本文转载自微信公众号《架构改进之路》,作者张章。转载本文请联系建筑改良之路公众号。大家好,我是张张,公众号《架构提升之路》的作者。通常,我们的一个请求将由三个服务处理。请求从客户端发出,到达代理层(执行一些公共逻辑,如逻辑、流控、审计等)。完成后发送给AppLayer(执行具体的业务逻辑)。执行后,发送到数据层(用于数据持久化)。然而,在分布式系统中,事情似乎很简单:错误是常态。因此,我们需要:为失败而设计。也就是说,当您的系统将错误视为正常流程时,系统就已经对错误免疫了。在这里,我将向大家介绍12种常见的设计思路。1、防御设计(DefensiveDesign)所谓防御设计,其实就是“防傻”,英文叫做IdiotProofing。说白了,用户有时会不自觉地做一些蠢事。我们在设计的时候应该尽量考虑一些不规则的交互行为。如果你的用户是猴子,你得写个包保证系统不被破坏。.例如Android开发中使用的MonkeyTest就是用于此目的。2.边缘案例(EdgeCase)的设计思想在测试领域比较常见,即我们在设计我们的设计案例时是否充分考虑了边缘案例中的系统行为。比较常见的例如是闰年情况、跨日情况等界线。3.MistakeProofing如何确保不会出现错误。比如在人机交互环节,是否可以进行输入校验?4.在进行解耦(Decoupling)设计时,即使是最基本的代码也应该符合开闭原则。Spring的IOC就是将对象的创建和维护,从原来由引用类负责的强耦合模式,转变为spring容器。而解耦的一般方法是将内部逻辑封装起来,对外暴露一个统一的API接口。调用者不需要知道被调用者的内部逻辑实现,只需要知道提供了哪些功能即可。再延伸一下,解耦的作用就是复用,把所有高内聚的函数分离成一个个的模块,然后像乐高积木一样,根据调用者的实际需要拼装起来。5.冗余所谓冗余是指对关键部件或组件进行重复配置,以保证在关键部件出现故障时有备份部件运行,从而保证系统能够继续提供服务。生活中的例子请参与飞机的双引擎设计。主从模式是冗余的体现。一般情况下,主实例负责提供所有服务,当主实例完全或部分不可用时,从实例完全替代主实例的全部或部分对外提供服务。6、重试(Retry)重试是分布式系统中处理暂时性故障的基本手段,简单有效(当然重试的前提是要求幂等性)。但重试也可能非常危险。会导致本地时间小的迅速升级为系统大故障,严重时会导致系统卡顿。举个简单的例子:如果我们的链接类似于上图,这里会发生什么?极端情况下重试次数达到5*5*5*5=625次。当链路中某一个服务的故障率异常时,就会启动重试风暴,因为重试会给服务器带来额外的开销和线程占用,然后其他新的请求形成队列,从而导致类似DDos的恶性事件发生形成。7、冷备(ColdStandby)冷备其实是冗余设计的一种表现形式,但会更侧重于“冷”,即当系统宕机时,需要手动启动系统进行替换主要下线实例与双机热备不同,更多体现在自动切换上。8.降额降额本质上是一种防御性设计或策略。假设微服务系统下的一个系统,服务A调用服务B,系统QPS为1000级。届时,如果B的服务挂掉,A的线程会在短时间内完全耗尽,导致假死,导致A的请求大量积压,雪上加霜,最终形成雪崩.9.容错(ErrorTolerance)从狭义上讲,容错一般是指在人机交互界面中需要对用户输入进行校验,以保证数据的准确性。广义上的容错应该是针对两个具有明确边界(例如服务和系统之间)的事物交互时可能出现的一切主观和客观异常的一种防御手段。常见的容错机制包括故障安全、故障恢复、故障转移和快速故障。failfast更多指的是快速失败,避免线程积压导致的系统雪球崩溃。failover是指故障转移。故障安全意味着故障安全。Failback是指自动故障恢复,将故障实例切换到备用实例。10.故障安全所谓故障安全是指在发生特定故障时,系统或服务不会对业务造成损害。例如:我们使用令牌进行安全登录也是故障安全的一种体现。如果token过期(比如时间过期),则用户无法登录,因为正常登录需要token有一个约束因子,就是时间。如果时间已经过去,则说明该约束不存在或不再有效,登录功能将无法正常使用。11.优雅降级(GracefulDegradation)服务降级类似于断路器,但降级更加温和优雅。Fuse是直接切断,防止异常进一步扩大导致雪崩,但我们的最终目标是提供尽可能多的服务,这就是优雅降级的概念。在一些异常情况或闪杀场景下,为保证核心服务(如产品订购、支付)的正常可用,部分非核心服务(如历史账单查询)将被放弃。这就是所谓的服务降级。在微服务框架中,一般使用Hystrix的@HystrixCommand或者Feign的@FeignClient来声明服务,然后为每个服务配置相应的fallback类,最后组合起来进行服务降级。12.耐久性(Durability)这里理解系统或数据的耐受性。比如为什么我们一定要将数据持久化到数据库中,因为它是依赖于数据库硬件各个维度的承受能力。补充作为设计者或开发者,应该敬畏墨菲定律。此外,还需要补充的一点是:监控(Monitoring)。我们系统有什么纬度监控,估计最多的就是常规的硬件状态监控。当然我理解这里的监控不仅要监控技术指标,还要监控业务指标。不然我们都是裸泳,等海水退去就什么都看不到了。监控其实是为了更好的主动防御。完善的告警监控体系,可以快速通知开发和运维,开发方完成应急修复,配合运维快速部署。