Sentinel

Sentinel

  • Sentinel介绍
    • 什么是Sentinel?
    • 为什么需要流量控制?
    • 为什么需要熔断降级?
    • 一些普遍的使用场景
    • 本文介绍参考:
      • Sentinel官网
      • 《Spring Cloud Alibaba 从入门到实战.pdf》
  • Sentinel下载/安装
  • 项目演示
    • 构建项目
    • 控制台概览
    • 演示之前需先明确:什么是资源?什么是规则?
    • ```什么是资源```
    • 什么是规则
    • 实时监控
    • 簇点链路
    • 流控规则
      • ```什么是流量控制?```
        • 演示项目代码
        • 演示
          • ```定义,规则 一:QPS ---> 直接 ---> 快速失败```, 流控模式为: *直接*
          • ```定义,规则二:QPS ---> 关联 ---> 快速失败,```流控模式为: *关联*
          • ```定义,规则三:QPS ---> 链路 ---> 快速失败,```流控模式为: *链路*
          • ```定义,规则四:并发线程数--->直接```; 流控模式为 “直接”
          • ```定义,规则五:并发线程数--->关联```;流控模式为关联
          • ```定义,规则六:并发线程数--->关联```;流控模式为链路
          • ```定义,规则七:QPS--->直接---> Warm Up```
          • ```定义,规则八:QPS--->直接---> 排队等待```
          • ```其他规则还有:```
    • 熔断规则
      • 三种 熔断策略
      • 熔断降级规则的几个重要属性
      • 演示
        • 定义规则一:慢调用比例
        • 定义规则二:异常比例
        • 定义规则三:异常数
    • 热点参数规则
    • 授权规则(来源访问控制规则)
      • 定义
      • 规则
      • 演示
    • 系统规则
    • 集群流控
  • ```@SentinelResource 注解的使用```
  • 规则持久化问题(动态规则扩展)
    • 引入依赖
    • 修改配置文件 application.yml
    • 启动Nacos,添加application.yml中配置的配置文件
    • 启动Sentinel,查看控制台
    • 终极验证:重启Sentinel、Nacos、项目,再查看配置是否还存在

Sentinel介绍

什么是Sentinel?

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

为什么需要流量控制?

流量是非常随机性的、不可预测的。前一秒可能还风平浪静,后一秒可能就出现流量洪峰了(例如双十一零点的场景)。然而我们系统的容量总是有限的,如果突然而来的流量超过了系统的承受能力,就可能会导致请求处理不过来,堆积的请求处理缓慢,CPUILoad飙高,最后导致系统崩溃。因此,我们需要针对这种突发的流量来进行限制,在尽可能处理请求的同时来保障服务不被打垮,这就是流量控制。

为什么需要熔断降级?

一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方API等。例如,支付的时候,可能需要远程调用银联提供的API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。见下图:
在这里插入图片描述
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用因此我们需要对不稳定的弱依赖服务进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。

一些普遍的使用场景

  • 在服务提供方( Service Provider )的场景下,我们需要保护服务提供方自身不被流量洪峰打垮。这时候通常根据服务提供方的服务能力进行流量控制,或针对特定的服务调用方进行限制。我们可以结合前期压测评估核心接口的承受能力,配置QPS模式的限流,当每秒的请求量超过设定的阈值时,会自动拒绝多余的请求。

  • 为了避免调用其他服务时被不稳定的服务拖垮自身,我们需要在服务调用端( ServiceConsumer )对不稳定服务依赖进行隔离和熔断。手段包括信号量隔离、异常比例降级、RT降级等多种手段。

  • 当系统长期处于低水位的情况下,流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。这时候我们可以借助Sentinel 的 WarmUp 流控模式控制通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,而不是在一瞬间全部放行。这样可以给冷系统一个预热的时间,避免冷系统被压垮。

  • 利用Sentinel的匀速排队模式进行“削峰填谷”,把请求突刺均摊到一段时间内,让系统负载保持在请求处理水位之内,同时尽可能地处理更多请求。

  • 利用Sentinel 的网关流控特性,在网关入口处进行流量防护,或限制API的调用频率。

本文介绍参考:

Sentinel官网

在这里插入图片描述

《Spring Cloud Alibaba 从入门到实战.pdf》

Sentinel下载/安装

  • 下载地址:https://github.com/alibaba/Sentinel/releases
    在这里插入图片描述
  • 直接运行下载的jar包即可
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 浏览器输入localhost:8080, 进入Sentinel控制台
    在这里插入图片描述
    在这里插入图片描述

项目演示

构建项目

  • 依赖包只需引入Sentinel即可
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.xl.projects</groupId>
		<artifactId>xl-springcloud-parent-pom</artifactId>
		<version>1.0.0</version>
	</parent>
	<artifactId>xl-sentinel-001</artifactId>

	<dependencies>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>


</project>
  • application.yml 配置文件
server:
  port: 8086
spring:
  application:
    name: sentinel-001
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080

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

控制台概览

启动项目,刷新控制台,发现仍然是空白,这是因为Sentinel控制台采用的 懒加载 策略:需要访问一次项目,Sentinel才会出现对应的项目信息。

编写一个Controller

package com.xl.projects.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.xl.projects.service.SentinelService;
import com.xl.projects.service.impl.SentinelServiceImpl;

@RestController
public class SentinelController {
	
	@Autowired
	private SentinelService SentinelService;
	
	@RequestMapping("/sentinel")
	public String test() {
		return "thisSentinel.";
	}
	
	@RequestMapping("/flow_control")
	public String test1() {
		return SentinelService.flowControl("thisIsFlowControl");
	}
	
}

访问:http://localhost:8086/sentinel
在这里插入图片描述
再次查看Sentinel控制台
在这里插入图片描述
下面会通过项目分别演示上图中红框中的部分规则的配置和效果

演示之前需先明确:什么是资源?什么是规则?

什么是资源

资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务或由应用程序调用的其它应用提供的服务甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。

什么是规则

围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。 在Sentinel控制台配置的内容。

参考官网:https://sentinelguard.io/zh-cn/docs/introduction.html

实时监控

连续请求http://localhost:8086/sentinel地址后,实时监控界面就会显示刚才请求的一些信息:
在这里插入图片描述

簇点链路

在这里插入图片描述

流控规则

  • 定义资源
  1. Sentinel的默认方式:将Controller中的接口地址当成资源

在还未定义之前,发现簇点链路中已经自动有了资源:
在这里插入图片描述
在这里插入图片描述

  1. java代码硬编码方式(不推荐,略)

  2. @SentinelResource注解方式(推荐):

    @SentinelResource注解官方文档

    在ServiceImpl实现类里面的加上注解@SentinelResource
    在这里插入图片描述
    在这里插入图片描述
    重启项目,在Sentinel控制台查看,
    在这里插入图片描述

  • 定义规则
    在这里插入图片描述

什么是流量控制?

流量控制,原理是监控应用流量的 QPS 或 并发线程数 等指标,当达到指定阈值时对流量进行控制,避免系统被瞬时的流量高峰冲垮,保障应用高可用性。同一个资源可以创建多条限流规则,一条限流规则由以下属性组成:

resource: 资源名,即限流规则的作用对象,默认请求路径。

limitApp: 流控针对的调用来源,若为 default 则不区分调用来源,默认值default

count: 限流阈值

grade: 限流阈值类型(1代表 QPS,0 代表并发线程数),默认值QPS

QPS: 当 QPS 超过某个阈值的时候,则采取措施进行流量控制。
QPS,每秒请求数,即在不断向服务器发送请求的情况下,服务器每秒能够处理的请求数量。

并发线程数: 线程数限流用于保护业务线程数不被耗尽。例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对高线程占用的情况,业内有使用隔离的方案,
比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离),或者使用信号量来控制同时请求的个数(信号量隔离)。
这种隔离方案虽然能够控制线程数量,但无法控制请求排队时间。当请求过多时排队也是无益的,直接拒绝能够迅速降低系统压力。
Sentinel线程数限流不负责创建和管理线程池,而是简单统计当前请求上下文的线程个数,如果超出阈值,新的请求会被立即拒绝。

strategy: 流控模式

直接拒绝(默认): 接口达到限流条件时,直接限流

关联: 当关联的资源达到阈值时,就限流自己(适合做应用让步):

当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,read_db 和 write_db 这两个资源分别代表数据库读写,我们可以给 read_db 设置限流规则来达到写优先的目的:设置 FlowRule.strategy 为 RuleConstant.RELATE 同时设置 FlowRule.ref_identity 为 write_db。这样当写库操作过于频繁时,读数据的请求会被限流。

链路:
解释1:只记录指定链路上的流量,指定资源从入口资源进来的流量,如果达到阈值,就可以限流。

解释2:该流控模式针对资源链路上的接口进行限流,例如:A、B两个接口都调用某一资源C,A -> C、B -> C 可以看成两个简单的链路,此时可以针对C配置链路限流,比如限制A调用C,而B调用C则不受影响,它的功能有点类似于针对来源配置项,但链路流控是针对上级接口,它的粒度更细。

解释3:NodeSelectorSlot 中记录了资源之间的调用链路,这些资源通过调用关系,相互之间构成一棵调用树。这棵树的根节点是一个名字为 machine-root 的虚拟节点,调用链的入口都是这个虚节点的子节点。
一棵典型的调用树如下图所示:

在这里插入图片描述

上图中来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeA,Sentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 FlowRule.strategy 为 RuleConstant.CHAIN,同时设置 FlowRule.ref_identity 为 Entrance1 来表示只有从入口 Entrance1 的调用才会记录到 NodeA 的限流统计当中,而对来自 Entrance2 的调用漠不关心。

调用链的入口是通过 API 方法 ContextUtil.enter(name) 定义的。

controlBehavior: 流控效果

快速失败(默认): 当 QPS 超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时

排队等待: 这种方式严格控制了请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。注意:这一效果只针对QPS流控,并发线程数流控不支持。

Warm Up

该方式主要用于系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。预热底层是根据令牌桶算法实现的。注意:该方式只针对 QPS 流控,对并发线程数流控不支持

预热底层是根据令牌桶算法实现的,源码对应得类在 com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController 中,算法中有一个冷却因子coldFactor,默认值是3,即请求 QPS 从 threshold(阈值) / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

比如通过 sentinel-dashboard 设定 testWarmUP 资源的 QPS 阈值为,流控效果为 warm up,预热时长为5秒,如下图所示,testWarmUP 资源刚开始限流的阈值为 20/3=6,但经过10秒的预热后,慢慢将阈值升至20, 如下图所示:
在这里插入图片描述

以上几种属性在 sentinel-dashboard 控制台对应的规则如下图:
在这里插入图片描述
以上参考:
1、Sentinel官网
2、https://blog.csdn.net/m0_71777195/article/details/126460960

演示项目代码

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.xl.projects</groupId>
		<artifactId>xl-springcloud-parent-pom</artifactId>
		<version>1.0.0</version>
	</parent>
	<artifactId>xl-sentinel-001</artifactId>

	<dependencies>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>


</project>

application.yml

server:
  port: 8086
spring:
  application:
    name: sentinel-001
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080
      web-context-unify: false

主启动类

package com.xl.projects;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Sentinel001Applicaiton {

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

}	

两个Controller

package com.xl.projects.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.xl.projects.service.SentinelService;

@RestController
public class FlowLimitController {
	
	@Autowired
	private SentinelService SentinelService;
	
	@RequestMapping("/front_limit")
	public String front() {
		return "后面的流程达到了阈值,前面的流程front被关联限流了";
	}
	
	
	
	@RequestMapping("/rear_reach")
	public String rear() {
		return SentinelService.flowControl("thisIsFlowControl");
	}
	
}

package com.xl.projects.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.xl.projects.service.SentinelService;
import com.xl.projects.service.impl.SentinelServiceImpl;

@RestController
public class SentinelController {
	
	@Autowired
	private SentinelService SentinelService;
	
	@RequestMapping("/sentinel")
	public String test() {
		return "thisSentinel.";
	}
	
	@RequestMapping("/relative_source")
	public String test2() {
		return SentinelService.flowControl("this is entry 1 : config flow limit");
	}
	
	@RequestMapping("/flow_control")
	public String test1() {
		return SentinelService.flowControl("this is entry 2");
	}
	
}

两个Service:一个接口,一个实现

package com.xl.projects.service;

public interface SentinelService {
	
	String flowControl(String flowController);
	
}

package com.xl.projects.service.impl;

import java.util.Date;

import org.springframework.stereotype.Service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.xl.projects.service.SentinelService;
import com.xl.projects.utils.ExceptionUtil;

@Service
public class SentinelServiceImpl implements SentinelService {

	@Override
//	@SentinelResource(value="service_flow_l",blockHandler="handleException",blockHandlerClass=ExceptionUtil.class)
	@SentinelResource(value="service_flow_l")
	public String flowControl(String flowController) {
		System.out.println(System.currentTimeMillis()+ ":+++++++++"+Thread.currentThread().getName());
		try {
			Thread.currentThread().sleep(3000);
		} catch (Exception e) {
			// Do Nothing
		}
		return flowController;
	}
	
	
	public String handleException(String flowController, BlockException ex) {
		
		return "this param is " +flowController+" ;Ops! Exception Occurs, ex: "+ ex.getMessage();
	}
	

}

一个工具类:后面的@SentinelResource注解需要用到

package com.xl.projects.utils;

import com.alibaba.csp.sentinel.slots.block.BlockException;

public class ExceptionUtil {
	
	public static String handleException (String flowController, BlockException ex) {
		
		return "single  alone CLASS for handling exception...";
		
	}
	
}

演示

定义,规则 一:QPS ---> 直接 ---> 快速失败, 流控模式为: 直接

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

资源
在这里插入图片描述

测试
在这里插入图片描述
在这里插入图片描述
如上图,达到了流量控制的预期。

定义,规则二:QPS ---> 关联 ---> 快速失败,流控模式为: 关联

在这里插入图片描述
解释: 如果关联的资源 /relative_resource 的QPS超过了1 ,那么资源 /sentinel 将会被限流

资源
在这里插入图片描述
测试,使用 postman 的并发测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击 《Run 并发测试》 之前,先看下访问资源 /sentinel的结果:
在这里插入图片描述
点击 《Run 并发测试》 之后,再看下访问资源 /sentinel的结果:
在这里插入图片描述
在这里插入图片描述
上图,符合关联资源的流量控制预期!

定义,规则三:QPS ---> 链路 ---> 快速失败,流控模式为: 链路

在这里插入图片描述
注:需添加如下配置否则,不会生效!
在这里插入图片描述
资源
在这里插入图片描述
测试:

*入口1的链路:http://192.168.8.6:8086/relative_source ,访问被限流*

在这里插入图片描述
入口2的链路:http://localhost:8086/flow_control 访问正常
在这里插入图片描述

定义,规则四:并发线程数--->直接; 流控模式为 “直接”

定义:超过3个线程,资源/relative_source就会被限流。
在这里插入图片描述
资源
在这里插入图片描述
测试: 使用JMeter测试,配置为 1秒内发送10个线程,如下
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
注:用浏览器也可,模拟并发测试,快速的连续刷新即可,但还是没有JMeter好使
在这里插入图片描述

定义,规则五:并发线程数--->关联;流控模式为关联

演示:略,参考规则二

定义,规则六:并发线程数--->关联;流控模式为链路

演示:略,参考规则三

定义,规则七:QPS--->直接---> Warm Up

流控效果为 Warm Up
在这里插入图片描述
资源:配置 /sentinel 即可
在这里插入图片描述

测试

  • 启动项目8086
  • 使用JMeter模拟突然发送大量请求
    在这里插入图片描述
    在这里插入图片描述
  • 观察流控效果
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
定义,规则八:QPS--->直接---> 排队等待

在这里插入图片描述
资源
在这里插入图片描述
测试:
在这里插入图片描述

其他规则还有:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
演示,略;可参考以上规则。

熔断规则

在这里插入图片描述

三种 熔断策略

Sentinel 提供以下几种熔断策略:

  1. 慢调用比例(SLOW_REQUEST_RATIO): 选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
  2. 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
  3. 异常数 (ERROR_COUNT): 当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

注意! 异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。

熔断降级规则的几个重要属性

Field说明默认值
resource资源名,即规则的作用对象
grade熔断策略,支持慢调用比例/异常比例/异常数策略慢调用比例
count慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow熔断时长,单位为 s
minRequestAmount熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)5
statIntervalMs统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)1000 ms
slowRatioThreshold慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

演示

定义规则一:慢调用比例

在这里插入图片描述
测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
但是,熔断5s后,访问带参数的地址http://localhost:8086/slow?p=5 (这个不是慢调用),则不会重新开始熔断,一切正常。
在这里插入图片描述

定义规则二:异常比例

略。注意!异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。

定义规则三:异常数

略.注意!异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。

热点参数规则

TODO…

授权规则(来源访问控制规则)

定义

很多时候,我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的黑白名单控制的功能。黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。

简单说,就是允许哪些客户端(调用方)访问,禁止哪些客户端(调用方)访问

规则

黑白名单规则(AuthorityRule)非常简单,主要有以下配置项:

  • resource:资源名,即限流规则的作用对象
  • limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB
  • strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式
    在这里插入图片描述

有个问题是:在这里配置的流控应用名称(limitApp), 在客户端(调用方)程序如何提供??

调用方需要在请求的Header里面添加一个字段用于存放应用的名称!

  1. 假设是调用方是Spring Cloud Gateway项目,则可以这样设置
    在这里插入图片描述
  2. 调用方式postman,则可以这样设置
    在这里插入图片描述
  3. 其他情况, 对应在请求的Header中设置就行了

那么,对应的, 在Sentinel授权规则应用里面需要获取调用方请求中的应用名称!

1.Sentinel提供了如下接口
在这里插入图片描述
可以解析 请求的原始信息:IP、 用户、 应用名称,应为是个接口所以需要实现它:

package com.xl.projects.utils;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;

@Component
public class SentinelParseHeader implements RequestOriginParser  {

   @Override
   public String parseOrigin(HttpServletRequest request) {
   	String origin = request.getHeader("appName");
   	if(StringUtils.isEmpty(origin)) 
   		origin = "blank";
   	return origin;
   }

}

演示

授权规则定义
在这里插入图片描述
资源
在这里插入图片描述
在这里插入图片描述
使用postman模拟访问
在这里插入图片描述
在这里插入图片描述

自定义异常:参见: https://blog.csdn.net/weixin_43715214/article/details/128859907

遗留问题: 如果集成至Nacos直接使注册的服务名称当作limitApp,这样不知道是否可行,待验证。。。

系统规则

TODO…
注意!阈值类型为 Load 时(仅对 Linux/Unix-like 机器生效)

集群流控

TODO…
没搞明白

@SentinelResource 注解的使用

参考官网:https://sentinelguard.io/zh-cn/docs/annotation-support.html
在这里插入图片描述

public class TestService {

    // 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 static 函数.
    @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
    public void test() {
        System.out.println("Test");
    }

    // 原函数
    @SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback")
    public String hello(long s) {
        return String.format("Hello at %d", s);
    }
    
    // Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数.
    public String helloFallback(long s) {
        return String.format("Halooooo %d", s);
    }

    // Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
    public String exceptionHandler(long s, BlockException ex) {
        // Do some log here.
        ex.printStackTrace();
        return "Oops, error occurred at " + s;
    }
}

规则持久化问题(动态规则扩展)

直接在 Sentinel 控制台配置的规则,重启应用后,所有的规则都消失了,这显然是不行的。 原因:Sentinel 控制台配置的规则是存在内存中的。

解决: 需要将文件持久化到 文件、数据库、注册中心等。
参考:官网说明:动态规则扩展

有多种方案,下面演示其中一种:将规则持久化到Nacos注册中心

引入依赖

在这里插入图片描述

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.xl.projects</groupId>
		<artifactId>xl-springcloud-parent-pom</artifactId>
		<version>1.0.0</version>
	</parent>
	<artifactId>xl-sentinel-001</artifactId>

	<dependencies>
		<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
		</dependency>

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

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>


</project>

修改配置文件 application.yml

在这里插入图片描述

server:
  port: 8086
spring:
  application:
    name: sentinel-001
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080
      web-context-unify: false
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            rule-type: flow  # flow代表“流控规则”,其他的规则可通过枚举类org.springframework.cloud.alibaba.sentinel.datasource.RuleType来查看     
        ds2:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-sentinel-degrade
            groupId: DEFAULT_GROUP
            rule-type: degrade  # degrade代表“熔断规则”,其他的规则可通过枚举类org.springframework.cloud.alibaba.sentinel.datasource.RuleType来查看     

启动Nacos,添加application.yml中配置的配置文件

先配置Nacos再修改application.yml文件,效果也是一样的;只要保证两个地方的配置是一致的,如dataId等
在这里插入图片描述
在这里插入图片描述

启动Sentinel,查看控制台

在这里插入图片描述
在这里插入图片描述
在Nacos上修改其中一个配置:流控规则, 在Sentinel中验证是否被动态加载了
在这里插入图片描述
在这里插入图片描述

终极验证:重启Sentinel、Nacos、项目,再查看配置是否还存在

在这里插入图片描述

重启后,规则仍然存在。验证成功!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/985.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【webrtc】ICE 到VCMPacket的视频内存分配

ice的数据会在DataPacket 构造是进行内存分配和拷贝而后DataPacket 会传递给rtc模块处理rtc模块使用DataPacket 构造rtp包最终会给到OnReceivedPayloadData 进行rtp组帧。吊炸天的是DataPacket 竟然没有声明析构方法。RtpVideoStreamReceiver::OnReceivedPayloadData 的内存是外…

3.网络爬虫——Requests模块get请求与实战

Requests模块get请求与实战requests简介&#xff1a;检查数据请求数据保存数据前言&#xff1a; 前两章我们介绍了爬虫和HTML的组成&#xff0c;方便我们后续爬虫学习&#xff0c;今天就教大家怎么去爬取一个网站的源代码&#xff08;后面学习中就能从源码中找到我们想要的数据…

普通Java工程师 VS 优秀架构师

1 核心能力 1.1 要成为一名优秀的Java架构师 只懂技术还远远不够&#xff0c;懂技术/懂业务/懂管理的综合型人才&#xff0c;才是技术团队中的绝对核心。 不仅仅是架构师&#xff0c;所有的技术高端岗位&#xff0c;对人才的综合能力都有较高的标准。 架构路线的总设计师 规…

安卓渐变的背景框实现

安卓渐变的背景框实现1.背景实现方法1.利用PorterDuffXfermode进行图层的混合&#xff0c;这是最推荐的方法&#xff0c;也是最有效的。2.利用canvas裁剪实现&#xff0c;这个方法有个缺陷&#xff0c;就是圆角会出现毛边&#xff0c;也就是锯齿。3.利用layer绘制边框1.背景 万…

多线程案例——阻塞队列

目录 一、阻塞队列 1. 生产者消费者模型 &#xff08;1&#xff09;解耦合 &#xff08;2&#xff09;“削峰填谷” 2. 标准库中的阻塞队列 3. 自己实现一个阻塞队列&#xff08;代码&#xff09; 4. 自己实现生产者消费者模型&#xff08;代码&#xff09; 一、阻塞队列…

【Pytorch】 理解张量Tensor

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 这是目录张量Tensor是什么&#xff1f;张量的创建为什么要用张量Tensor呢&#xff1f;总结张量Tensor是什么&#xff1f; 在深度学习中&#xff0c;我们经常会遇到一个概念&#xff…

更改Hive元数据发生的生产事故

今天同事想在hive里用中文做为分区字段。如果用中文做分区字段的话&#xff0c;就需要更改Hive元 数据库。结果发生了生产事故。导致无法删除表和删除分区。记一下。 修改hive元数据库的编码方式为utf后可以支持中文&#xff0c;执行以下语句&#xff1a; alter table PARTITI…

Vue初入,了解Vue的发展与优缺点

作者简介&#xff1a;一名计算机萌新、前来进行学习VUE,让我们一起进步吧。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;我叫于豆豆吖的主页 前言 从本章开始进行Vue前端的学习&#xff0c;了解Vue的发展&#xff0c;以及背后的故事。 一.vue介…

ASEMI代理瑞萨TW9992AT-NA1-GE汽车芯片

编辑-Z TW9992AT-NA1-GE是一款低功耗NTSC/PAL模拟视频解码器&#xff0c;专为汽车应用而设计。它支持单端、差分和伪差分复合视频输入。集成了对电池短路和对地短路检测&#xff0c;先进的图像增强功能&#xff0c;如可编程的自动对比度调整&#xff08;ACA&#xff09;和MIPI…

【Linux】网络编程套接字(下)

&#x1f387;Linux&#xff1a; 博客主页&#xff1a;一起去看日落吗分享博主的在Linux中学习到的知识和遇到的问题博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a; 看似不起波澜的日复一日&#xff0c;一定会在某一天让你看见坚持…

ASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B

编辑&#xff1a;ll ASEMI代理MIMXRT1064CVJ5B原装现货NXP车规级MIMXRT1064CVJ5B 型号&#xff1a;MIMXRT1064CVJ5B 品牌&#xff1a;NXP /恩智浦 封装&#xff1a;LFGBA-196 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 引脚数量&#xff1a;196 类型&#…

【Hadoop-yarn-01】大白话讲讲资源调度器YARN,原来这么好理解

YARN作为Hadoop集群的御用调度器&#xff0c;在整个集群的资源管理上立下了汗马功劳。今天我们用大白话聊聊YARN存在意义。 有了机器就有了资源&#xff0c;有了资源就有了调度。举2个很鲜活的场景&#xff1a; 在单台机器上&#xff0c;你开了3个程序&#xff0c;分别是A、B…

Redis知识点汇总

前言 梳理知识 说一下项目中的Redis的应用场景 首先知道Redis的5大value类型: string,list,hash, set ,zset 2.基本上是缓存 3.为的是服务无状态, 4.无锁化 Redis是单线程还是多线程 1.无论什么版本,工作线程就一个 2.6.x高版本出现IO多线程

三天吃透操作系统面试八股文

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

基于python的超市历年数据可视化分析

人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据可视化分析目录人生苦短 我用python一、数据描述1、数据概览二、数据预处理0、导入包和数据1、列名重命名2、提取数据中时间&#xff0c;方便后续分析绘图三、数据可视化1、美国各个地区销售额的分布&…

进阶C语言——指针(二)【题目练习】

文章目录1.指针和数组概念的理解2.指针和数组笔试题解析一维数组字符数组二维数组1.指针和数组概念的理解 指针和数组 数组&#xff1a;能够存放一组相同类型的元素&#xff0c;数组的大小取决于数组的元素个数和元素类型指针&#xff1a;也是地址或指针变量&#xff0c;大小是…

Spring Cloud -- GateWay

为什么需要网关在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去调用。这样的话会产生很多问题&#xff0c;例…

重构·改善既有代码的设计.04之重构手法(下)完结

1. 前言 本文是代码重构系列的最后一篇啦。前面三篇《重构改善既有代码的设计.01之入门基础》、《重构改善既有代码的设计.02之代码的“坏味道”》、《重构改善既有代码的设计.03之重构手法&#xff08;上&#xff09;》介绍了基础入门&#xff0c;代码异味&#xff0c;还有部…

【Java】你真的懂封装吗?一文读懂封装-----建议收藏

博主简介&#xff1a;努力学习的预备程序媛一枚~博主主页&#xff1a; 是瑶瑶子啦所属专栏: Java岛冒险记【从小白到大佬之路】 前言 write in the front: 如何理解封装&#xff1f; 试想&#xff1a;我们使用微波炉的时候&#xff0c;只用设置好时间&#xff0c;按下“开始”…

[C++]反向迭代器

目录 前言&#xff1a; 1 对反向迭代器的构造思想 2 实现反向迭代器 3 完整代码 前言&#xff1a; 本篇文章主要介绍了STL容器当中的反向迭代器&#xff0c;可能有朋友会说&#xff1a;“反向迭代器有什么好学的&#xff1f;不一样还是迭代器吗&#xff0c;我正向能写出来&…