前言
在一个微服务系统中,经常会出现一个服务依赖于多个服务,而一个调用逻辑会调用多个服务的情况出现。如果出现某个服务提供者出现故障不可用,就会导致服务消费者不可用,又由于是同步调用最后线程全部阻塞在服务消费者身上,最后导致服务消费者也不可用。这就是服务雪崩。
对于这种情况我们一般由以下解决方案:
- 超时机制:服务调用超过一定时间,直接返回
- 服务限流:通过限制流量的方式保证核心服务不会出现故障
- 服务熔断:在应用一段时间内出现异常达到一定比例就会服务熔断,等待服务可用才会继续调用
- 服务降级:在服务不可用的情况下,服务不在调用,但我们会有一个fallback机制,返回一个mock数据给消费者。
Sentinel基本介绍
Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。
资源(摘自官方文档)
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则(摘自官方文档)
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
Spring Cloud Alibaba整合Sentinel
这这里是在springcloud gateway层面进行的流量控制。
启动 Sentinel 控制台
官方文档;
第一次启动界面是空的,需要调用一遍接口才会在列表出现服务
http://localhost:8080/#/login;默认用户名密码:sentinel/sentinel

添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
添加yml配置
spring:
cloud:
sentinel:
enabled: true
eager: true
transport:
dashboard: localhost:8080 ## sentinel控制台ip:port
client-ip: localhost
效果

连续访问后

Sentinel控制台规则
既然有了Sentinel控制台,那么我们就可以在控制台对规则进行配置(其实可以代码配置和配置中心配置读取等方法)。
现在我们通过Sentinel控制台简单介绍Sentienl规则。
流控规则
流控就是监控QPS和并发线程数指标达到阈值时进行限流,避免瞬时流量高峰将系统打垮。
阈值类型
限制请求的指标
- QPS:每秒请求数,表示1s内有多少请求通过,这个量由单机阈值控制
- 线程数:当前最多有多少线程可以访问资源。这里主要是防止业务线程执行过慢导致所有线程资源被消耗干净
流控模式
基于调用关系的流量控制
直接:针对于当前指定资源进行流控
关联:这种模式针对于2个资源存在竞争情况,假设A,B 2资源存在竞争,当A流量达到一定的程度时候,我们需要对B资源进行限流,比如存在数据库竞争,A对数据库请求频繁假设不对B加以限制可能导致数据库崩溃。
链路:由入口资源进行限流,假设有一个链路,A,B2个资源都调用了当前资源,当当前资源达到阈值会对指定的入口资源进行限流
流控效果
快速失败(默认):当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException
Warm Up:预热/冷启动方式。在预热时长内达到阈值,防止系统突然接受阈值的请求导致系统崩溃,所以以这种方式将阈值缓慢增加到阈值上限,底层令牌桶算法
排队等待:严格控制请求通过的间隔时 间,也就是让请求以均匀的速度通过,底层漏桶算法
降级规则
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。
熔断策略
慢调用比例:设置一个最大RT(超过这个时间就为慢请求),当慢请求/所有请求大于比例阈值就会出现熔断,熔断熔断时长,当过了熔断时长会出现一个Half状态,当下一个请求不是慢请求就解除熔断,是慢请求就继续熔断。
异常比例:当单位时长内请求数目大于最小请求数,并且异常的比例大于比例阈值,则接下来的熔断时长内请求会自动被熔断
异常数:当单位时长内请求数目大于最小请求数,并且异常数目超过异常数阈值之后会自动进行熔断
热点规则
热点就是经常访问的数据,而热点规则可以对我们接口请求的参数进行限流,假设我们有一部分id是热点,而我们要对其调用getInfo/id请求查看详情。我们不能对这个接口全部进行限流,而要只针对id=11111进行限流就可以使用热点规则。
注意: 资源名必须是@SentinelResource(value=”资源名”)中 配置的资源名,热点规则依赖于注解

系统规则
对于整个应用从几个维度来看达到指标便进行限流。
- Load(仅对 Linux/Unixlike 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5
- **RT(单位ms)**:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护
- 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护
- CPU 使用率:当系统 CPU 使用率超过阈值即触发系统保护
