Bootstrap

【深入理解SpringCloud微服务】Sentinel功能详解

上一篇文章《Sentinel实战与原理剖析》我们没有对Sentinel的功能进行讲解,本篇文件将对它们进行详细的解析。

在这里插入图片描述

Sentinel控制台

首先要下载Sentinel控制台的jar包,或者下载sentinel-dashboard的源码自行编译也可以。
在这里插入图片描述

然后启动控制台:

在这里插入图片描述
引入maven依赖:

	<dependencies>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
			<version>2.2.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>2.3.12.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
			<version>2.3.12.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-bootstrap</artifactId>
			<version>3.0.2</version>
		</dependency>
	</dependencies>
  • spring-cloud-starter-alibaba-sentinel:Sentinel的starter,里面包含了sentinel-transport-simple-http、sentinel-annotation-aspectj、sentinel-spring-webmvc-adapter等依赖,并且自带自动配置,比起单独引入sentinel-core、sentinel-transport-simple-http等方便许多
  • spring-boot-starter-actuator:Sentinel控制台依赖需要通过actuator暴露的端点收集服务监控信息,以在“实时监控”中进行展示。
  • spring-cloud-starter-bootstrap:启动时加载bootstrap配置文件。

bootstrap.yml文件:

server:
  port: 8888

spring:
  application:
    name: demo
  cloud:
    sentinel:
      transport:
      	# sentinel控制台的地址
        dashboard: 127.0.0.1:8080
        # 本服务以sentinel控制台交互的端口
        port: 8719

# 暴露actuator的/actuator/sentinel端点        
management:
  endpoints:
    web:
      exposure:
        include: '*'   

编写一个简单的Controller:

/** 
 * @author huangjunyi 
 * @date 2024年4月13日 上午8:19:32
 * @desc 
 */
@RestController
public class HelloController {
	
	@GetMapping("/hello")
	public String hello() {
		return "hello world";
	}

}

启动服务,测试/actuator/sentinel端点是否正常暴露:

在这里插入图片描述

调一遍/hello接口,这样Sentinel才会有信息。

在这里插入图片描述

进入控制台查看,默认账号密码是sentinel/sentinel。

在这里插入图片描述

在【簇点链路】可以查看接口信息:

在这里插入图片描述

配置流控规则:
在这里插入图片描述

调用/hello接口测试流控规则:

在这里插入图片描述

【实时监控】可以查看不同时间点的通过QPS、拒绝QPS、响应时间(ms):

在这里插入图片描述

在这里插入图片描述

流控规则

流控规则可以设置【阈值类型】、【流控模式】、【流控效果】,其中【流控效果】只有当【阈值类型】是QPS是,才能设置。

在这里插入图片描述

阈值类型

【阈值类型】可以设置QPS或并发线程数,QPS是每秒请求数,如果设置为QPS的话,那么当接口的每秒请求数达到指定阈值时,则触发限流,设置为并发线程数时也是类似的规则。

在这里插入图片描述

流控模式

【流控模式】有“直接”、“关联”、“链路”三种。

直接

以【阈值类型】为QPS为例:“直接”就是当QPS指定资源名对应的接口QPS达到单机阈值设置的值时,该接口后续的请求将被限流。比如以下例子,当/hello接口的QPS达到2时,则后续的请求将会被限流。

在这里插入图片描述

关联

“关联”是指关联资源达到阈值后,当前资源则被限流。

我们改造一下接口:

/** 
 * @author huangjunyi 
 * @date 2024年4月13日 上午8:19:32
 * @desc 
 */
@RestController
public class HelloController {
	
	@Autowired
	private RestTemplate restTemplate;
	
	@GetMapping("/hello")
	public String hello() {
		return "hello " + restTemplate.getForObject("http://localhost:8888/world", String.class);
	}
	
	@GetMapping("/world")
	public String world() {
		return "world";
	}
	
	@GetMapping("/my")
	public String my() {
		return "my " + restTemplate.getForObject("http://localhost:8888/world", String.class);
	}

}

现在/hello接口和/my接口,都会调用到/world接口。

在这里插入图片描述

控制台配置:

在这里插入图片描述

那么此时关联资源(/world接口)的QPS达到2时,后续对当前资源(/hello接口)的请求都会被限流。

在这里插入图片描述

链路

“链路”是指当前资源的QPS达到阈值时,入口资源会被限流。

由于“链路”模式的当前资源必须是被@SentinelResource注解修饰的,并且入口资源只能通过方法调用的方式调用当前资源,不能通过http请求的方式进行调用,否则会不生效。因此改造一下工程:

把/world接口抽成Service接口,/hello和/my两个接口调用world():

/** 
 * @author huangjunyi 
 * @date 2024年4月13日 上午8:19:32
 * @desc 
 */
@RestController
public class HelloController {
	
	@Autowired
	private HelloService helloService;
	
	@GetMapping("/hello")
	public String hello() {
		return "hello " + helloService.world();
	}
	
	@GetMapping("/my")
	public String my() {
		return "my " + helloService.world();
	}

}

Service添加@SentinelResource注解:

/** 
 * @author huangjunyi 
 * @date 2024年4月13日 下午2:24:56
 * @desc 
 */
@Service
public class HelloService {
	
	@SentinelResource("world")
	public String world() {
		return "world";
	}

}

此时接口调用情况变成如下这样:

在这里插入图片描述

然后进行规则配置:/hello接口和/my接口都调用了wolrd接口,那么像下面这样配置之后,当world接口的QPS达到限流阈值时,入口资源对应的/hello接口就会被限流。

在这里插入图片描述

在这里插入图片描述

注意,为了要让链路模式流控规则生效,还要配置入口资源关闭聚合。

可以添加配置spring.cloud.sentinel.web‐context‐unify: false。

server:
  port: 8888

spring:
  application:
    name: demo
  cloud:
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080
        port: 8719
      # 入口资源关闭聚合
      web-context-unify: false
        
management:
  endpoints:
    web:
      exposure:
        include: '*'   

或者引入sentinel-web-servlet依赖,并添加一个CommonFilter过滤器,给CommonFilter添加初始化属性CommonFilter.WEB_CONTEXT_UNIFY为false。

		<dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-web-servlet</artifactId>
            <version>1.8.5</version>
        </dependency>
    @Bean
    public FilterRegistrationBean<CommonFilter> sentinelFilterRegistration() {
        FilterRegistrationBean<CommonFilter> registration = new FilterRegistrationBean();
        registration.setFilter(new CommonFilter());
        registration.addUrlPatterns("/*");
        // 入口资源关闭聚合
        registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
        registration.setName("sentinelFilter");
        registration.setOrder(1);
        return registration;
    }

在这里插入图片描述

流控效果

【流控效果】指的是底层的限流算法,配置不同的流控效果,那么Sentinel底层使用的限流算法就不一样,自然就有不同的流控效果。

快速失败

使用的是滑动时间窗算法,统计每秒的QPS数,达到阈值则限流。

比如下面配置的单机阈值为2,流控效果为快速失败,那么Sentinel底层使用滑动时间窗算法统计每秒的QPS,当前资源的QPS达到2时,后续对当前资源的请求都会被限流。

在这里插入图片描述

Warm Up

使用的是令牌桶算法,需要配置【预热时长】,在【预热时长】内限流阈值会均衡增长,直到达到了【预热时长】后,限流阈值增加到【单机阈值】指定的值。

比如下面配置【流控效果】为“Warm Up”,指定【预热时长】为5,【单机阈值】为10。那么服务起订之后,当前资源(“/hello”接口)的限流阈值将会在5秒内匀速增长达到10。

在这里插入图片描述

排队等待

当配置的【流控效果】为“排队等待”时,【单机阈值】指的是每秒匀速处理的请求个数,然后还有配置【超时时间】表示当请求被限流时,等待的超时时长。

比如下面配置【流控效果】为“排队等待”,【单机阈值】为10,【超时时间】为200,那么表示当前资源(“/hello”接口)每秒处理10个请求,当请求被限流时,等待200毫秒。

在这里插入图片描述

在这里插入图片描述

熔断降级规则

熔断规则里面需要配置【熔断策略】,包含熔断策略:“慢调用比例”、“异常比例”、“异常数”。

在这里插入图片描述

然后最下面三个配置项是固定配置项。

  • 熔断时长:当触发熔断时,断路器打开的时长。
  • 最小请求数:当指定【统计时长】内请求数达到最小请求数时,熔断规则才生效。
  • 统计时长:熔断规则的统计时长。

在这里插入图片描述

慢调用比例

当【熔断策略】配置为“慢调用比例时”,需要设置【最大 RT】和【比例阈值】两个配置项。【最大 RT】是指最大响应时间,当一次请求的响应时长超过了这个时间限制时,就会被记为一次慢调用;【比例阈值】是指触发熔断的慢调用比例,当【统计时长】内的慢调用比例阈值达到了【比例阈值】指定的比例值时,触发熔断。

在这里插入图片描述

异常比例

当【熔断策略】配置为“异常比例”时,需要配置【比例阈值】配置项,该配置项指的是当前资源在【统计时长】指定的时长内异常比例达到了【比例阈值】指定的比例值时,触发熔断。

在这里插入图片描述

异常数

当【熔断策略】配置为“异常数”时,需要配置【异常数】配置项,当前资源在【统计时长】的时长内异常数达到【异常数】指定的数值时,触发熔断。

在这里插入图片描述

在这里插入图片描述

热点参数规则

热点参数限流需要指定参数,因此我们改造一下/hello接口,添加一个接口参数。

	@GetMapping("/hello")
	public String hello(@RequestParam int num) {
		return "hello " + helloService.world();
	}

【热点规则】中的配置项包含:参数索引、统计窗口时长、单机阈值、参数类型、参数值、限流阈值。

比如像下面这样配置后,当我们请求/hello?num=1在5秒内超过2次是则被限流,而num参数是其他值时则在5秒内超过3次时被限流。
在这里插入图片描述

在这里插入图片描述

系统自适应保护

【系统保护规则】是用于保护整个服务的,而不是针对一个服务中的某个资源进行保护。

【系统保护规则】需要配置“阈值类型”以及与之对应的阈值,当系统的对应指标达到了阈值时,后续对该系统的所有请求都将被限流。

阈值类型包括:

  • LOAD:系统负载,就是Linux的top命令里load average的第一个值
  • RT:系统所有入口流量的平均响应时长
  • 线程数:系统所有入口流量的并发线程数
  • 入口QPS:系统所有入口流量的QPS
  • CPU使用率:系统CPU使用率

在这里插入图片描述

在这里插入图片描述

黑白名单

黑白名单在【授权规则】中配置,需要配置【资源名】和【流控应用】两个配置项,【资源名】就是当前授权规则保护的当前资源,【流控应用】指的是调用方,黑白名单限制的就是调用方法。

在这里插入图片描述
在这里插入图片描述

集群流控

【集群流控】分两种角色:“Token Client”和“Token Server”。服务作为“Token Client”请求“Token Server”获取token,当获取不到时则进行限流。

在这里插入图片描述

我们添加“Token Server”时需要指定【机器类型】:

  • 应用内机器:选择注册到Sentinel上的某个应用所在的机器作为“Token Server”。
  • 外部指定机器:指定一台外部的机器作为“Token Server”。

在这里插入图片描述

然后我们可以在【流控规则】中勾选【是否集群】开启集群流控,需要配置【集群阈值模式】:

单机均摊:集群总阈值 = 连接到“Token Server”的“Token Client”数量 * 均摊阈值。
总体阈值:指定的阈值就是集群的总阈值。
在这里插入图片描述

在这里插入图片描述

;