Alibaba Sentinel实现服务熔断与限流

1. 概述

Sentinel是阿里开源的一套用于服务容错的综合性解决方案,以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
Sentinel具有以下特性:

  • 丰富的应用场景
  • 完备的实时监控
  • 广泛的开源生态
  • 完善的SPI扩展点

Sentinel架构如下图所示:
Sentinel架构
Sentinel 分为两个部分:
核心库(Java 客户端):不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
控制台(Dashboard):基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

2. 安装Sentinel控制台

官网下载最新的Sentinel控制台程序,目前最新版本是1.8.4,JDK最低为1.8,Sentinel默认使用端口为8080,使用命令java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar 启动控制台程序,默认用户名和密码都是sentinel
Sentinel登陆页

3. 开发Sentinel微服务

3.1. 引入核心依赖

新建SpringBoot项目,引入核心依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

3.2. application.yml配置文件

server:
  port: 8300
spring:
  application:
    name: alibaba-sentinel
  cloud:
    nacos:
      discovery:
        server-addr: xx.xx.xx.xx:8848
      username: nacos
      password: nacos
    sentinel:
      transport:
        dashboard: xx.xx.xx.xx:8080
        port: 8719
management:
  endpoints:
    web:
      exposure:
        include: '*'

3.3. 主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class SentinelApplication {

    public static void main(String[] args) {
        SpringApplication.run(SentinelApplication.class, args);
    }
}

3.4. controller类

@RestController
@RequestMapping("/sentinel")
public class SentinelController {

    @GetMapping("/getSentinelInfo")
    public String getSentinelInfo() {
        return "This is sentinel info,now is " + LocalDateTime.now();
    }

    @GetMapping("/getSentinelDetails")
    public String getSentinelDetails() {
        return "This is sentinel details,now is " + LocalDateTime.now();
    }
}

启动Sentinel微服务,查看Sentienl控制台并没有发现Sentinel微服务的接口,由于Sentinel采用的是懒加载方式,需要先执行一次接口访问
Sentinel接口监测页面

3.5. 几个基本概念和功能

资源:就是Sentinel要保护的东西,可以是Java应用程序中的任何内容,可以是一个服务,也可以是一个方法,甚至可以是一段代码
规则:用来定义如何进行保护资源的,作用在资源之上,定义以什么样的方式来保护资源,主要包括流量控制规则、熔断降级规则以及系统保护规则
流量控制:用于调整网络包的数据,任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的,需要根据系统的处理能力对流量进行控制
熔断降级:当检测到调用链路中某个资源出现不稳定的表现,如请求响应时间长或异常比例升高时,则对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源而导致级联故障。Sentinel通过并发线程数进行限制和通过响应时间对资源进行降级
系统负载保护:Sentinel同时提供系统维度的自适应保护能力,当系统负载较高时,如果还持续让请求进入可能会导致系统崩溃,无法响应,在集群环境下,会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求

4. 流控规则

流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性
点击簇点链路,可以看到访问过的接口,在接口的操作中点击流控
添加流控规则
或者点击流控规则,再点击新增流控规则
新增流控规则
新增流控规则
新增流控规则
资源名:唯一名称,默认请求路径
针对来源:Sentinel可以针对调用者进行限流,填写微服务名称,默认default(不区分来源)
阈值类型/单机阈值
QPS(每秒请求量):当调用该api的QPS达到阈值的时候,进行限流
线程数:当调用该api的线程数达到阈值的时候,进行限流
是否集群:不需要集群

4.1. 流控模式

流控模式
直接:api达到限流条件时,直接限流
关联:当关联的资源达到阈值时,就限流自己
链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流),api级别的针对来源

4.1.1. 直接流控模式

当指定的接口达到限流条件时开启限流
直接限流

4.1.2. 关联流控模式

关联流控模式
使用jmeter调用接口/sentinel/getSentinelDetails测试,QPS大于配置的单机阈值
jmeter测试
再次访问接口/sentinel/getSentinelInfo,会发现已经被限流
再次访问接口

4.1.3. 链路流控模式

当从某个接口过来的资源达到限流条件时,开启限流,与针对来源配置项的区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,粒度更细

4.2. 流控效果

流控效果
快速失败:直接失败,抛异常
Warm Up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值
排队等待:均速排队,让请求以均速的速度通过,阈值类型必须设置为QPS,否则无效

5. 熔断规则

Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出DegradeException)
左侧点击簇点链路,选择接口,在接口后面点击熔断
熔断
或者点击熔断规则,再点击新增熔断规则
新增熔断规则
进入新增熔断规则界面

5.1. 慢调用比例

即平均响应时间,当1S内持续进入n个请求,对应时刻的平均响应时间(秒级)均超过阈值(ms),那么在接下来的时间窗口之内,对这个方法的调用都会自动熔断,RT默认最大值为4900ms,超出此阈值都会算作4900ms
慢调用比例

5.2. 异常比例

当资源每秒请求量>=n,并且每秒异常总数通过量的比值超过阈值之后,资源进入降级状态,即在接下来的时间窗口之内,对这个方法的调用都会自动地返回,异常比率的阈值范围是[0.0,1.0],代表0% - 100%
异常比例

5.3. 异常数

当资源近1分钟的异常数目超过阈值之后会进行熔断,由于统计的时间窗口是分钟级别的,若timeWindow小于60s,则结束熔断状态后仍可能再进入熔断状态
异常数

6. 热点规则

热点即经常访问的数据,很多时候希望统计或者限制某个热点数据中访问频次最高的TopN数据,并对其访问进行限流或者其他操作,允许将规则具体到参数上
热点规则配置
后端controller代码为:

@GetMapping("/getSentinelInfoByIdAndName")
@SentinelResource(value = "sentinelInfoByIdAndName")
public String getSentinelInfoByIdAndName(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "name", required = false) String name) {
    return "This is sentinel info for id:" + id + " and name:" + name;
}

在浏览器输入地址http://localhost:8300/sentinel/getSentinelInfoByIdAndName?id=1,多次刷新请求,可以看到异常
第一个参数访问异常
在浏览器输入地址http://localhost:8300/sentinel/getSentinelInfoByIdAndName?name=zhangsan,多次刷新请求,不会发生异常
参数例外项允许对一个参数的具体值进行流控,编辑定义的规则,增加参数例外项
参数例外项
配置异常处理,后端代码如下:

@GetMapping("/getSentinelInfoByIdAndName")
@SentinelResource(value = "sentinelInfoByIdAndName", blockHandler = "dealHandler")
public String getSentinelInfoByIdAndName(@RequestParam(value = "id", required = false) Long id, @RequestParam(value = "name", required = false) String name) {
    return "This is sentinel info for id:" + id + " and name:" + name;
}

public String dealHandler(Long id, String name, BlockException exception) {
    return "The interface is current-limited, request parameters is id:" + id + " name:" + name + "exception is:" + exception;
}

再次调用接口
异常

7. 系统规则

系统保护规则是从应用级别的入口流量进行控制,从单台机器的load、CPU使用率、平均RT、入口QPS和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量,比如Web服务或Dubbo服务端接收的请求,都属于入口流量。
系统规则
系统规则有如下模式
Load自适应:系统的load1作为启发指标,进行自适应系统保护,当系统load1超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR阶段),系统容量由系统maxOps * minRt估算得出,设定参考值一般是CPU cores * 2.5
CPU usage:当系统CPU使用率超过阈值即触发系统保护(0.0 - 1.0),比较灵敏
平均RT:当单台机器上所有入口流量的平均RT达到阈值即触发系统保护,单位毫秒
并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护
入口QPS:当单台机器上所有入口流量的QPS达到阈值即触发系统保护

8. 授权规则

很多时候,需要根据调用来源来判断该次请求是否允许放行,这时候可以使用Sentinel的来源访问控制的功能,来源访问控制根据资源的请求来源限制资源是否通过
授权规则
若配置白名单,则只有请求来源位于白名单内的才可通过
若配置黑名单,则请求来源位于黑名单时不通过,其他的请求通过

9. 整合OpenFeign

9.1. 引入核心依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

9.2. application.yml配置

feign:
  sentinel:
    enabled: true

9.3. Feign接口

@FeignClient(value = "alibaba-service-provider", fallback = ProviderServiceFallback.class)
public interface ProviderService {

    @GetMapping("/service/getServiceInfo")
    String getServiceInfo();
}

9.4. 容错处理类

@Component
public class ProviderServiceFallback implements ProviderService {

    @Override
    public String getServiceInfo() {
        return "Service downgraded, please try again later!";
    }
}

9.5. controller层实现

@Resource
private ProviderService providerService;

@GetMapping("/getProviderInfo")
public String getProviderInfo() {
    String serviceInfo = providerService.getServiceInfo();
    return "This is provider service info:" + serviceInfo;
}

9.6. 验证

启动服务提供服务和Sentinel服务
在Sentinel控制台配置流控规则
流控
注意选择上图方法,配置流控规则
配置流控规则
浏览器输入地址http://localhost:8300/sentinel/getProviderInfo,多次刷新
服务熔断

10. 规则持久化

上面的配置存在一个问题,一旦我们重启应用,sentinel规则将消失,因此需要将限流配置规则持久化进Nacos保存,只要刷新服务提供微服务某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对服务提供微服务上sentinel上的流控规则持续有效

10.1. 引入核心依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

10.2. application.yml配置

spring:
    sentinel:
      datasource:
        ds:
          nacos:
            server-addr: xx.xx.xx.xx:8848
            dataId: ${spring.application.name}
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

10.3. nacos业务规则配置

nacos配置规则
resource:资源名称;
limitApp:来源应用;
grade:阈值类型,0表示线程数,1表示QPS;
count:单机阈值;
strategy:流控模式,0表示直接,1表示关联,2表示链路;
controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;

10.4. 验证

启动sentinel微服务,刷新Sentinel控制台即可
查看流控规则

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值