作者 | 宿何  阿里云高级开发工程师

导读:疫情期间,“卡”成了很多人线上体验的关键词。线上预约购买口罩时,突然不能付款了;在线选课,被提示请求过多,系统无法响应;在线办公/教学时,图像或声音卡住了……这些可用性下降的场景严重的影响了用户体验,也降低了公司的工作效率。面对“卡”住了的情况 ,作为开发者的我们,需要预先通过一些手段来提前对不稳定的因素进行防护,同时在突发流量的情况下,也要具备快速止损的能力。

近年来,微服务的稳定性一直是开发者非常关注的话题。随着业务从单体架构向分布式架构演进以及部署方式的变化,服务之间的依赖关系变得越来越复杂,业务系统也面临着巨大的高可用挑战。

如何保障服务的可用性?这是一个非常庞大的话题,涉及到方方面面,其中一个重要的手段就是流控降级。

为什么要进行流控降级?

流量是非常随机性的、不可预测的。前一秒可能还风平浪静,后一秒可能就出现流量洪峰了(例如 双11 零点的场景)。

然而我们的系统容量总是有限的,如果突如其来的流量超过了系统的承受能力,就可能会导致请求处理不过来,堆积的请求处理缓慢,CPU/Load 飙高,最终导致系统崩溃。因此,我们需要针对这种突发的流量来进行限制,在尽可能处理请求的同时来保障服务不被打垮。

一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。

例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。

现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的服务进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。

那么是不是服务的量级很小就不用进行限流防护了呢?是不是微服务的架构比较简单就不用引入熔断保护机制了呢?

其实,这与请求的量级、架构的复杂程度无关。很多时候,可能正是一个非常边缘的服务出现故障而导致整体业务受影响,造成巨大损失。我们需要具有面向失败设计的意识,在平时就做好容量规划和强弱依赖的梳理,合理地配置流控降级规则,做好事前防护,而不是在线上出现问题以后再进行补救。

那么大家可能想问:有没有什么方法来快速进行高可用防护呢?如何做到均匀平滑的用户访问?如何预防这些不稳定因素带来的影响?今天我们就来大家具体分享承载阿里巴巴近 10 年双十一大促稳定性场景的流量控制组件 —— Sentinel 的实践。

Sentinel:面向云原生微服务的流量控制、熔断降级组件

Sentinel 是阿里巴巴开源的,面向分布式服务架构的流量控制组件,目前在 GitHub 已收获 11,071 Star。

该组件主要以流量为切入点,从流量控制、流量整形、熔断降级、系统自适应保护等多个维度来帮助开发者保障微服务的稳定性。Sentinel 承接了阿里巴巴近 10 年的 双11 大促流量的核心场景,例如秒杀、冷启动、消息削峰填谷、集群流量控制、实时熔断下游不可用服务等,是保障微服务高可用的利器。

GitHub 标星 11000+,阿里开源的微服务组件如何连续 10 年扛住双十一大促?_第1张图片

Sentinel 里的两个核心概念 —— 资源与规则。资源(Resource)可以理解为需要进行防护的代码块(或调用),比如 SQL 访问、REST API 访问、Dubbo 服务调用、Reactive 响应式服务、API 网关的路由访问,甚至是任意的代码块,都可以作为 Sentinel 的资源。

用户可以通过 Sentinel API 或注解手动进行资源埋点,或者通过 Sentinel 提供的框架适配模块引入依赖一键接入。规则则是针对某个资源进行的控制手段,比如我们可以针对某个服务、方法来配置流控规则、降级规则等来达到高可用防护的效果。

其核心特性与技术如下:

  • 基于滑动窗口结构的实时统计,性能好的同时又可以保证统计的准确性;

  • 高度可扩展能力:基础核心 + SPI 接口扩展能力,用户可以方便地扩展流控、通信、监控等功能;

  • 多样化的流量控制策略(资源粒度、调用关系、流控指标、流控效果等多个维度),提供分布式集群流控的能力,同时提供热点流量探测和防护的能力;

  • 对不稳定服务进行熔断降级和隔离;


  • 全局维度的系统负载自适应保护,根据系统水位实时调节流量;

  • 覆盖 API Gateway 场景,为 Spring Cloud Gateway、Zuul 提供网关流量控制的能力;

  • 云原生场景提供 Envoy 服务网格集群流量控制的能力;

  • 实时监控和规则动态配置管理能力。

同时,Sentinel 提供一个简单的所见即所得的控制台,可以接入控制台对服务进行实时监控,同时可以在控制台实时配置、管理规则:

GitHub 标星 11000+,阿里开源的微服务组件如何连续 10 年扛住双十一大促?_第2张图片

下面介绍 Sentinel 的一些常见的使用场景和最佳实践:

在服务提供方(Service Provider)的场景下,我们需要保护服务提供方自身不被流量洪峰打垮。这时候通常根据服务提供方的服务能力进行流量控制,或针对特定的服务调用方进行限制。我们可以结合前期压测评估核心接口的承受能力,配置 QPS 模式的限流,当每秒的请求量超过设定的阈值时,会自动拒绝多余的请求。

为了避免调用其他服务时被不稳定的服务拖垮自身,需要在服务调用端(Service Consumer)对不稳定服务依赖进行隔离和熔断。手段包括信号量隔离、异常比例降级、RT 降级等多种手段。

当系统长期处于低水位的情况下,流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。这时候我们可以借助 Sentinel 的 WarmUp 流控模式控制通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,而不是在一瞬间全部放行。这样可以给冷系统一个预热的时间,避免冷系统被压垮。

利用 Sentinel 的匀速排队模式进行“削峰填谷”,把请求突刺均摊到一段时间内,让系统负载保持在请求处理水位之内,同时尽可能地处理更多请求。

利用 Sentinel 的网关流控特性,在网关入口处进行流量防护,同时可以针对不同用户、IP 来分别限制 API 的调用频率。在 Istio+Envoy 架构下快速接入 Sentinel RLS token server,为 Envoy 集群提供全局流量控制的能力。

Sentinel 的开源生态

Sentinel 有着丰富的开源生态,覆盖微服务、API Gateway 与 Service Mesh 几大核心生态。

Sentinel 开源不久就被纳入 CNCF Landscape 版图,并且也成为 Spring Cloud 官方推荐的流控降级组件之一。社区提供 Spring Cloud、Dubbo、gRPC 等常用框架的适配,开箱即用;同时支持 Reactive 生态,支持 Reactor、Spring WebFlux 异步响应式架构。Sentinel 也在逐渐覆盖 API Gateway 和 Service Mesh 场景,在云原生架构中发挥更大的作用。

GitHub 标星 11000+,阿里开源的微服务组件如何连续 10 年扛住双十一大促?_第3张图片

Sentinel 多语言演进及未来展望

Sentinel 初期主要面向 Java 微服务,同时也在朝着多语言扩展的方向不断探索。去年中旬,Sentinel 推出 C++ 原生版本,同时针对 Service Mesh 场景,Sentinel 也推出了 Envoy 集群流量控制的支持,可以解决 Service Mesh 架构下多语言限流的问题。

近期,Sentinel 多语言俱乐部又迎来新的一员 —— Sentinel Go 首个原生版本正式发布,为 Go 语言的微服务提供流控降级、系统保护等特性的原生支持。开发者只需简单的几步即可快速接入 Sentinel,享受到以下能力:

  • 精确限制接口级别的 QPS,防止打垮核心接口;
  • 削峰填谷,激增的请求排队等待处理;
  • 自适应的系统维度流量保护,结合 load 等系统指标以及服务实时的请求量和响应时间来自动拒绝多余的流量,尽可能地提升吞吐量的同时保证服务不挂;
  • 实时的秒级监控能力,通过监控日志了解系统的实时流量情况。

在接下来的版本中,Sentinel Go 将会陆续推出熔断降级、热点参数统计与流控等一系列的稳定性保障能力。同时,社区也会陆续提供与常用的框架和云原生组件的整合模块。

未来,Sentinel 还会朝着多语言和云原生的方向持续演进。

Sentinel 目前已支持 Java、Go、C++ 三种语言,未来社区还会支持更多语言。同时我们会不断完善 API Gateway 及 Service Mesh 的流控场景,如原生 Istio Service Mesh 整合,方便开发者在各种云原生场景下快速接入 Sentinel 享受高可用防护的能力。

社区后面也计划提供与 Prometheus 等云原生监控组件的整合,可以利用 Sentinel 的指标统计数据进行接口级别的监控,同时结合 K8S HPA 弹性机制、自适应流控等,来提供自动化的稳定性保障。

云原生团队招人啦

如果你符合以下条件,欢迎投递简历加入我们!

  • 3 年以上分布式系统相关经验,熟悉高并发,分布式通信,存储等相关技术;
  • 熟练掌握 Golang/Java 语言开发,具备 Python, Shell 等其它一种或多种语言开发经验;
  • 对容器和基础设施相关领域的技术充满热情,有 PaaS 平台相关经验,在相关的领域如 Kubernetes、Serverless 平台、容器技术、应用管理平台等有丰富的积累和实践经验(如产品落地,创新的技术实现,开源的突出贡献,领先的学术研究成果等)。

简历投递通道:[email protected]

GitHub 标星 11000+,阿里开源的微服务组件如何连续 10 年扛住双十一大促?_第4张图片

“阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”