微服务流量控制组件Sentinel

一、简介

Sentinel是阿里开源的项目,是一款面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来保障服务的稳定性。

核心思想是:根据对应资源配置的规则来为资源执行相应的流控/降级/系统保护策略,官网地址为:https://github.com/alibaba/Sentinel/wiki。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 的主要特性如下图:

微服务流量控制组件Sentinel_第1张图片

Sentinel实现限流、隔离、降级、熔断等功能,本质要做的就是两件事情:

  • 统计数据:统计某个资源的访问数据(QPS、RT等信息)

  • 规则判断:判断限流规则、隔离规则、降级规则、熔断规则是否满足

这里的资源就是希望被Sentinel保护的业务,例如项目中定义的controller方法就是默认被Sentinel保护的资源。

二、架构

Sentinel 分为两个部分:

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

所以,所有的统计以及计算,都是在客户端完成的。

微服务流量控制组件Sentinel_第2张图片 Sentinel客户端架构图

上图是来自官网的总体架构图,这张图上可以清晰的看到整个流量控制以责任链的模式进行的,每一个slot负责特定的处理。

  • NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;

  • ClusterBuilderSlot 则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;

  • StatisticSlot 则用于记录、统计不同纬度的 runtime 指标监控信息;

  • FlowSlot 则用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制

  • AuthoritySlot 则根据配置的黑白名单和调用来源信息,来做权限控制

  • DegradeSlot 则通过统计信息以及预设的规则,来做熔断降级

  • SystemSlot 则通过系统的状态,例如 load1 等,来控制总的入口流量,来做系统规则控制

三、限流/熔断执行过程及源码

3.1、微服务限流

微服务限流是指在规定的时间段内限制服务的请求量,以保护系统。主要作用是防止突发流量而导致系统崩溃,比如秒杀、抢购等场景,就需要对系统中微服务进行限流。

现实中限流例子:银行取号系统。

3.2、微服务熔断

服务熔断是指调用方访问服务时通过断路器做代理进行访问,断路器会持续观察服务返回的成功、失败的状态,当失败超过设置的阈值时断路器打开,请求就不能真正地访问到服务了。当监控到该微服务正常工作后,再次恢复该调用链路。

3.3、微服务降级

在服务发生熔断后,一般会让请求走事先配置的处理方法,这个处理方法就是一个降级逻辑。服务降级是对非核心、非关键的服务进行降级。

微服务的限流、降级、熔断等容错机制不可避免回造成用户请求失败或变慢,从而在一定程度上影响用户体验,所以策略的制定需要以系统压测的结果为参考,并在用户体验与系统稳定性之间进行平衡取舍。

Sentinel 限流执行过程如下:

微服务流量控制组件Sentinel_第3张图片

Sentinel限流、熔断降级源码架构图

四、规则管理以及推送

Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则 和 热点参数规则

一般来说,规则的推送有下面三种模式:

推送模式 说明 优点 缺点
原始模式 API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource) 简单,无任何依赖 不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境
Pull 模式 扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等 简单,无任何依赖;规则持久化 不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。
Push 模式 扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源。 规则持久化;一致性;快速 引入第三方依赖

生产环境下,一般采用Push模式,即:控制台将配置规则推送到远程配置中心,例如Zookeeper。Sentinel客户端监听Zookeeper,获取配置变更的推送消息,完成本地配置更新。 架

构图如下

微服务流量控制组件Sentinel_第4张图片

五、实时监控

Sentinel 客户端会记录资源访问的秒级数据(若没有访问则不进行记录)并保存在本地日志中,Sentinel 控制台可以通过Sentinel 客户端预留的 HTTP API 从秒级监控日志中拉取监控数据,并进行聚合,也就是说同一个服务下的所有机器的簇点信息会被汇总,并且秒级地展示在"实时监控"下。

目前 Sentinel 控制台中监控数据聚合后直接存在内存中,未进行持久化,且仅保留最近 5 分钟的监控数据。

当然,如果监控数据要持久化,也可以扩展实现,官网有demo。

六、使用

管理端配置和使用demo见官网。

6.1、按url限流

设置 sentinel 提供的 CommonFilter 来拦截所有的访问

@Configuration
public class webConfig {
 @Bean
 public FilterRegistrationBean sentinelFilterRegistration() {
 FilterRegistrationBean registration = new FilterRegistrationBean();
 registration.setFilter(new CommonFilter());
 registration.addUrlPatterns("/*");
 registration.setName("sentinelFilter");
 registration.setOrder(1);
 return registration;
 }
 }

或者设置

spring.cloud.sentinel.filter.enabled = true

6.2 按资源限流(@SentinelResource)

资源:可以是任何东西,一个服务,服务里的方法,甚至是一段代码。

@SentinelResource 注解包含以下属性:

  • value:资源名称,必需项(不能为空)

  • entryType:entry 类型,可选项(默认为 EntryType.OUT)

  • blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

  • fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 - exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:

  • 返回值类型必须与原函数返回值类型一致;

  • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;

  • fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。

  • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

demo如下:

@GetMapping("/fallback/{id}")
//同时添加SentinelResource注解的fallback和blockHandler属性 exceptionsToIgnore被标注的异常将会被 原样抛出
@SentinelResource(value = "falllback", fallback = "fallbackHandler", blockHandler = "blockHandler", exceptionsToIgnore = {ArrayIndexOutOfBoundsException.class})
public String fallback(@PathVariable Long id){
 if (id < 0 || id > 3) {
 throw new NullPointerException("无对应的记录");
 }
 return "success";
}

//保证方法签名与原方法一致或加一个 Throwable 类型的参数
public String fallbackHandler(Long id, Throwable e) {
 return "出现未知的记录";
}

//处理Sentinel限流
public String blockHandler(Long id, BlockException e){
 return "BlockException限流";
}
  • fallback:若本接口出现未知异常,则调用fallback指定的接口。

  • blockHandler:若本次访问被限流或服务降级,则调用blockHandler指定的接口。

6.3 控制台配置

  • 按url限流: 如下图,控制台配置资源名为访问路径,一般为controller下全路径

    微服务流量控制组件Sentinel_第5张图片

  • 按资源限流: 如下图,控制台配置资源名为@SentinelResource注解对应的value值。

    微服务流量控制组件Sentinel_第6张图片

9 同类组件功能对比

微服务流量控制组件Sentinel_第7张图片

你可能感兴趣的:(微服务,微服务,sentinel,java,mysql)