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

设计一个稳定的微服务系统不得不考虑的场景

时间:2023-03-22 11:47:53 科技观察

我们的生产环境经常会出现一些不稳定的情况,比如:大促期间的瞬时洪峰流量导致系统超过最大负载,负载飙升,以及系统崩溃导致用户无法下单。“黑马”热点爆破缓存,DB坏掉,排挤正常流量,调用者被不稳定的服务拖累,线程池爆满,导致整个调用链路卡死。这些不稳定的场景可能会导致严重的问题。后果。您可能想问:如何实现统一流畅的用户访问?如何防止流量过大或服务不稳定的影响?下面介绍两种面对交通不稳定因素的方法。它们也是我们在设计高可用系统之前必须考虑的两个能力。它们是服务流量治理中非常关键的部分。流量控制流量非常随机且不可预测。前一秒可能还风平浪静,下一秒就可能车水马龙(比如双十一午夜的场景)。每个系统和服务都有其容量上限。如果突然出现的流量超过了系统的承受能力,可能会导致请求无法处理,累积的请求处理缓慢,CPU/Load飙升,最终导致系统崩溃。所以,我们需要对这种突发流量进行限制,同时尽可能的处理请求,保证服务不被打断,这就是流量控制。融合和降级一个服务往往会调用其他模块,这些模块可能是另一个远程服务、数据库或第三方API。例如支付时,可能需要远程调用银联提供的API;要查询某个产品的价格,可能需要查询数据库。但是,无法保证此依赖服务的稳定性。如果依赖的服务不稳定,请求的响应时间变长,调用服务的方法响应时间也会变长,线程就会堆积,最终可能会耗尽业务本身的线程池,以及服务本身也会改变。无法使用。现代微服务架构是分布式的,由许多服务组成。不同的服务相互调用,形成复杂的调用链路。以上问题在链接调用中会产生放大效应。如果复杂链路上某个环不稳定,可能会逐层级联,最终导致整条链路不可用。因此,我们需要对不稳定的弱依赖服务进行熔断降级,暂时切断不稳定的调用,避免局部的不稳定因素造成整体雪崩。Q:很多同学在问,那么服务级别小是不是就不需要做流量控制和限流保护了?是不是因为微服务的架构比较简单,所以不需要引入熔断保护机制?A:其实这跟请求的大小和架构的复杂度没有关系。在很多情况下,可能是一个非常边缘的服务故障影响了整体业务并造成了巨大的损失。需要有面向失败的设计意识,平时做好容量规划和强弱依赖的组合,合理配置流控降级规则,做好事前保护,而不是事后补救出现在线问题。在流量控制、降级和容错的背景下,我们有多种方式来描述我们的治理解决方案。下面我将介绍一套开放的、通用的、面向分布式服务架构、覆盖全链路异构生态的服务治理。标准的OpenSergo,我们来看看OpenSergo是如何定义流控降级和容错的标准的,有哪些实现支持这些标准,它能帮助我们解决什么问题?OpenSergo流控降级容错v1alpha1标准在OpenSergo中,我们结合Sentinel等框架的场景实践,抽象出标准的CRD用于流控降级容错场景的实现。我们可以认为一个容错治理规则(FaultToleranceRule)由以下三部分组成:Target:针对什么样的请求Strategy:容错或者控制策略,比如流控、熔断、并发控制、自适应过载protection,outlierinstanceremoval等FallbackAction:触发后的回退行为,比如返回错误或者状态码,我们来看看OpenSergo对于常见流控降级场景的具体标准定义,它是如何解决我们的问题的?前文提到,微服务框架只要适配OpenSergo,就可以通过统一的CRD进行流控降级等治理。无论是Java、Go还是Mesh服务,无论是HTTP请求还是RPC调用,还是数据库SQL访问,我们都可以通过这个统一的容错治理规则CRD,为微服务架构中的每一个环节配置容错治理,确保我们服务链接的稳定性。让我们详细看一下OpenSergo在每个特定场景下的配置。流量控制以下示例定义了集群流量控制的策略。集群整体维度不超过每秒180个请求。示例CRYAML:apiVersion:fault-tolerance.opensergo.io/v1alpha1kind:RateLimitStrategymetadata:name:rate-limit-foospec:metricType:RequestAmountlimitMode:Globalthreshold:180statDuration:"1s"这样一个简单的CR会给我们系统配置流量控制能力。流量控制能力相当于应用的安全气囊。超出系统服务能力的请求将被拒绝。具体逻辑可以由我们自定义(如返回指定内容或跳转到某个页面)。断路器保护下面的例子定义了一个慢调用比率断路器策略,例子CRYAML:apiVersion:fault-tolerance.opensergo.io/v1alpha1kind:CircuitBreakerStrategymetadata:name:circuit-breaker-slow-foospec:strategy:SlowRequestRatiotriggerRatio:'60%'statDuration:'30s'recoveryTimeout:'5s'minRequestAmount:5slowConditions:maxAllowedRt:'500ms'这个CR的语义是:当30s内超过500ms的请求比例达到60%时,请求数达到5,会自动触发Fuse,熔断恢复时间为5s。想象一下,在工作高峰期。当一些下游服务提供商遇到性能瓶颈时,甚至可能影响业务。我们为一些非关键的服务消费者配置这样的规则。当一定时间内的慢调用比例或错误比例达到一定条件时,自动触发熔断器,服务调用一段时间后会直接返回Mock的结果,方便调用者得到保证。不被不稳定的服务拖累,也给不稳定的下游服务一些“喘息”的时间,同时保证整个业务环节的正常运行。流控降级和容错标准的实现Sentinel介绍下面是一个支持OpenSergo流控降级和容错标准的项目Sentinel。Sentinel是阿里巴巴开源的分布式服务架构流控组件。主要以流量为切入点,帮助开发者从流量控制、流量整形、断路器降级、系统自适应保护等多个维度保障微服务的安全。稳定。Sentinel的技术亮点:高扩展性:基础核心+SPI接口扩展能力,用户可以方便的扩展流控、通信、监控等功能多样化的流控策略(资源粒度、调用关系、流控指标、流控效果等维度)),提供分布式集群流控能力,热点流量检测和防护,熔断和降级不稳定服务,全局维度隔离系统负载自适应保护,根据系统水位实时调整流量,覆盖APIGateway场景,针对SpringCloudGateway和Zuul提供网关流量控制能力云原生场景提供Envoy服务网格集群流量控制能力实时监控和规则动态配置管理能力一些常见的使用场景:在服务提供者场景中,我们需要保护服务提供者自己不被o被流量高峰淹没。这时通常会根据服务提供商的服务能力进行流量控制,或者对特定的服务调用者进行限制。我们可以结合之前的压力测试评估核心接口的承载能力,在QPS模式下配置限流。当每秒请求数超过设定的阈值时,多余的请求会被自动拒绝。为了避免在调用其他服务时被不稳定的服务拖累,我们需要在服务调用端(ServiceConsumer)对不稳定服务的依赖进行隔离和融合。手段包括信号量隔离、异常比率降级、RT降级等手段。当系统长期处于低水位,流量突然增加时,直接将系统拉到高水位可能会瞬间压垮系统。这时候我们可以利用Sentinel的WarmUp流控方式,控制通过的流量缓慢增加,在一定时间内逐渐增加到上限阈值,而不是瞬间全部释放。这使冷系统有时间预热并防止冷系统不堪重负。利用Sentinel的统一排队模式“削峰填谷”,将请求尖峰分散在一段时间内,使系统负载保持在请求处理水平内,尽可能多地处理请求。利用Sentinel的网关流控特性,在网关入口实现流量保护或限制API调用频率。阿里云微服务解决方案提供了完全符合阿里云OpenSergo微服务标准的企业级产品MSE。MSE服务治理企业版中的流量治理能力可以理解为商业版的Sentinel。我们也简要总结了MSE流量治理和社区解决方案在流量控制降级和容错场景下的能力对比。接下来我将基于MSE演示如何通过流量控制和断路器降级来保护我们的系统,让我们从容面对不确定的流量和一系列不稳定的场景。配置流控规则我们可以在监控详情页面查看各个接口的实时监控状态。我们可以点击界面概览右上角的“添加保护规则”按钮来添加流量控制规则:我们可以配置最简单的QPS方式的流量控制规则,比如上面的例子,就是限制单机数量机接口每秒调用不超过80次。监控查看流量控制效果配置好规则后稍等片刻,在监控页面可以看到流量限制效果:被拒绝的流量也会返回错误信息。MSE内置的框架有默认的流控处理逻辑,比如Web接口受限后返回429TooManyRequests,DAO层受限后抛出异常等。如果用户想更灵活的自定义各层的流控处理逻辑,可以通过SDK访问和配置自定义流控处理逻辑。总结流控降级和容错是我们在设计一个稳定的微服务系统时不得不考虑的场景。如果我们在设计每一个系统的时候,花很多心思去设计系统的流控降级和容错,这会成为我们每一个开发者头疼的问题。那么我们接触和设计了这么多系统的流控降级,有没有什么共同的场景、最佳实践、设计标准和规范,甚至参考实现可以沉淀出来呢?本文从场景简单介绍了OpenSergo的流量控制和断路器保护标准,同时也介绍了Sentinel流量保护的背景和手段。最后通过实例介绍如何使用MSE服务治理的流量保护能力来保护您的应用。