Sentinel:服务的熔断和流控

#1. 关于熔断和流控

#1.1. 熔断

微服务架构的系统通常会包含多个微服务,各个微服务可能部署在不同的机器上并通过网络进行通信,那么就不可避免会遇到 “网络请求超时” 、“微服务不可用” 等问题,这就会进一步引起依赖它的微服务不可用,这样不断引发服务故障的现象称为『雪崩效应』,最终的结果是整个应用系统瘫痪。

为了解决上述问题,编程领域(参考现实生活)提出了熔断器:

使用熔断器模式,如果请求出现异常,所有请求都会直接返回,而不会等待或阻塞,这样可以减少资源的浪费。

熔断器所造成的这种现象也叫『快速失败(fast fall)』。

#1.2. 流控

限流功能指的是 Sentinel(类似于过滤器、拦截器的效果)在收到请求后,拒绝请求的放行(至 Controller),而是直接返回,从而减少对 Controller,乃至 Service 的触发执行。

TIP

熔断和限流的区别在于,熔断是确确实实发生了错误,而限流责任人为(根据设置)强行让一部分请求被打回。

#1.3 Sentinel

Sentinel( [ˈsentɪnl] )以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Spring Cloud Alibaba Sentinel 同时兼具了熔断器和流控的功能。

#2. Sentinel 的底层工作流程

Spring Cloud Alibaba Sentinel 的底层工作流程伪代码如下:

1. 初始化上下文;
try {
  2. 熔断、流控逻辑的判断,判断当前请求是否能继续执行;
  3. 执行 “真·代码”;
} catch (BlockException e) {
  4. 上述第 2 步未能通过,会抛出 BlockException ,表示请求被拒绝
  return;
} catch (Exception e) {
  5. 业务异常,记录、统计异常信息
  throw e;
} finally {
  6. 收尾工作:曾经创建的资源该回收的回收,该清除的清除
}

Copied!

注意

仔细回想一下,上述的代码执行流程非常类似于 JDBC 和 Spring AOP 环绕通知( @Around )的 try-catch-finally 流程。

如果上述伪代码的真实情况如下:

ContextUtil.enter("上下文名称,例如:sentinel_spring_web_context");
Entry entry = null;
try {
    entry = SphU.entry("资源名称,例如:/rpc/openfein/demo", EntryType.IN or EntryType.OUT ); // 这背后有一个 Slot 链
    return doBusiness(); // 这里是执行业务方法,被 Sentinel “保护” 起来了
} catch (Exception e) {
    if (!(e instanceof BlockException)) Tracer.trace(e);  // 记录调用异常
    throw e;
} finally {
    if (entry != null) entry.exit(1); // 收尾工作:曾经创建的资源该回收的回收,该清除的清除
    ContextUtil.exit();
}

Copied!

熔断降级规则说明

熔断降级规则(DegradeRule)包含下面几个重要的属性:

Field

说明

resource

资源名,即规则的作用对象

grade

熔断策略,支持 慢调用比例 / 异常比例 / 异常数策略

count

慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);

异常比例 / 异常数模式下为对应的阈值

timeWindow

熔断时长,单位为 s

minRequestAmount

熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)

statIntervalMs

统计时长(单位为 ms),如 60 * 1000 代表分钟级(1.8.0 引入)

slowRatioThreshold

慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

流控级规则说明

流控规则(FlowRule)包含下面几个重要的属性:

Field

说明

resource

资源名,即限流规则的作用对象

grade

限流类型,支持 QPS / 并发线程数

count

限流阈值

limitApp

流控针对的调用来源,若为 default 则不区分调用来源

strategy

调用关系限流策略

controlBehavior

流量控制效果,支持直接拒绝 / Warm Up / 匀速排队

#3. sentinel-dashboard 的下载安装

sentinel-dashboard 是基于 Spring Boot 开发的控制台。打包后可以直接运行,不需要额外的 Tomcat 等应用容器。Sentinel 控制台不仅能展示服务流控、熔断降级相关的数据,还可以通过配置的方式动态的为 Sentinel 客户端下发流量控制的指令。

我们需要下载并安装的是 sentinel-dashBoard ,下载地址:https://github.com/alibaba/Sentinel/releases (opens new window)

注意:启动 sentinel-dashboard 需要 JDK 版本为 1.8 及以上版本。

使用如下命令启动控制台:

java -Dserver.port=8858 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar

Copied!

  • -Dserver.port=8858用于指定 Sentinel 控制台端口为 8858 。默认是 8080 。我们给它改成不常用的端口。
  • -Dproject.name=sentinel-dashboard指定 Sentinel 控制台程序的名称。

说明

如果你有多张网卡的话,你还需要指定使用哪张网卡(IP)来接受各个微服务上报的信息:

-Dcsp.sentinel.heartbeat.client.ip=192.168.xxx.xxx

访问网址:http://127.0.0.1:8858(opens new window)

从 1.6.0 起,sentinel-dashboard 引入基本的登录功能,默认用户名和密码都是 sentinel 。当然也可以通过 JVM 参数的方式进行修改。

  • -Dsentinel.dashboard.auth.username=sentinel用于指定控制台的登录用户名为 sentinel ;
  • -Dsentinel.dashboard.auth.password=123456用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel;
  • -Dserver.servlet.session.timeout=7200用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;

Sentinel 本身就是一个 Spring Boot 应用,所以修改 jar 包内部的 application.properties 文件也是可以修改配置的。

#4. 关于 Sentinel 的使用方式

Spring Cloud Alibaba Sentinel 可以分别用在服务的 “请求发起方” 和 “请求被调方” 2 方。由于

  • 请求发起方使用的是 OpenFeign ,因此这种情况下 Sentinel 是和 OpenFeign 进行整合;
  • 请求被调用使用的是 Spring MVC,因此这种情况下 Sentinel 是和 Spring MVC 进行整合。

同时又由于 Sentinel 兼具熔断和流控两个功能,因此这里就有 4 种情况

  • 在服务发起方项目中,整合 OpenFeign 进行实现熔断功能;
  • 在服务发起方项目中,整合 OpenFeign 进行实现限流功能;
  • 在服务被调方项目中,整合 Spring MVC 进行实现熔断功能;
  • 在服务被调方项目中,整合 Spring MVC 进行实现限流功能;

这样以来功能上就出现了重叠荣誉,因此在实际使用中我们是这样安排的:

  • 在服务发起方,Sentinel 整合 OpenFeign 实现熔断功能;
  • 在服务被调方,Sentinel 整合 Spring MVC 实现限流功能;