Sentinel熔断限流真的太丝滑了

阅读本文大概需要20分钟,但是还是要动手实验的哈,实践是检验真理的唯一标准。感觉博主整理的不错的可以给个关注,本号后续陆续推出干货

流量控制&熔断降级产品对比

SentinelHystrixResilience4j
隔离策略信号量隔离(并发线程数隔离)线程池隔离/信号量隔离信号量隔离
熔断降级策略基于响应时间、异常比率、异常数基于异常比率基于异常比率、响应时间
实时统计实现滑动窗口滑动窗口Ring Bit Bufffer
动态规则配置支持多种数据源支持多种数据源有限支持
扩展性多个扩展点插件的形式接口的形式
基于注解的支持支持支持支持
限流基于QPS,支持基于调用关系的限流有限的支持Rate Limiter
流量整形支持预热模式、匀速器模式、预热派对模式不支持简单的Rate Limiter
系统自适应保护支持不支持不支持
控制台提供开箱即用的控制台、可配置规则、查看秒级监控、机器发现简单的监控查看

Sentinel 介绍

Sentinel 概述

Sentinel是阿里巴巴出品的面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来保障微服务的稳定性

Sentinel 组成

  • 核心库:主要是指Java客户端,不依赖任何框架、库,能够运行与java7及以上的版本运行时环境,同时对Dubbo、Spring Cloud等框架也有较好的支持
  • 控制台:控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等

Sentinel 特性

alt

Sentinel 相关概念

资源

资源是Sentinel的关键概念。它可以是Java应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。只要通过Sentinel API定义的代码,就是资源、能够被Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源

规则

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

Sentinel 优势

  • 友好的控制面板
  • 支持实时监控
  • 支持多种限流、支持QPS限流,线程数限流以及多种限流策略
  • 支持多种降级模式、支持按平均返回时间降级,按多种异常数降级、按异常比率降级等
  • 方便扩展开发,支持SPI模式对chain进行扩展
  • 支持链路的关联、可以实现按照链路统计限流,系统保护,热门资源保护等

SpringBoot+Sentinel

SpringBoot 环境信息

  • SpringBoot 2.1.4.RELEASE
  • JDK8
  • Sentinel 1.7.2

内置加载限流规则

  • pom加入sentinel依赖

    		<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.7.2</version>
    </dependency>
  • 创建TestController

    @RestController
    public class TestController {
    @GetMapping("/hello")
    public String hello(){
    // 限流的资源名称
    try (Entry entry = SphU.entry("hello")){
    return "hello sentinel";
    }catch (BlockException e){
    return "系统繁忙,请稍后";
    }
    }
    @PostConstruct
    public void initFlowRules(){
    List<FlowRule> list = new LinkedList<>();
    FlowRule rule = new FlowRule();
    // 限流资源名称
    rule.setResource("hello");
    // 限流策略
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    // 限流数量定义QPS每秒能通过的请求个数
    rule.setCount(2);
    list.add(rule);
    // 加载限流规则
    FlowRuleManager.loadRules(list);
    }
    }
  • 此时启动应用,访问资源hello,每秒慢速点击访问可以正常访问,如果快速点击出现系统繁忙,请稍后

alt

通过上面我们也能看到限流规则是在代码中写好的, 如果后续要修改的话,需要重新编译非常的麻烦,现在Sentinel提供了一个控制台,通过控制台我们就能动态的修改限流规则,现在我们看下怎么使用Sentinel控制台来实现限流策略

Sentinel 控制台启动

  • 下载地址:https://github.com/alibaba/Sentinel/releases

  • 启动

    java -Dserver.port=8850 -jar sentinel-dashboard-1.8.4.jar
  • 浏览器访问 localhost:8050 账号密码默认sentinel sentinel

SpringBoot应用与Sentinel控制台绑定

  • pom加入依赖

    		<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.7.2</version>
    </dependency>
  • JVM启动时添加参数

    -Dcsp.sentinel.dashboard.server=localhost:8850
    -Dproject.name=SentinelQuickStartDemo
  • 重启应用并通过浏览器访问 /hello接口几次,查看控制台中实时监控效果

    alt
  • 动态设置限流规则

    • 首先取消代码中的规则设置,注释掉规则代码
alt
  • 打开控制台设置限流规则
alt
alt
alt
  • 访问应用接口,查看限流规则是否生效
alt

Sentinel 定义资源的方式

Sentinel除了基本的定义资源的方式外,还有其它的定义资源的方式,具体如下:

  • 抛出异常的方式定义资源
  • 返回布尔值的方式定义资源
  • 异步调用支持
  • 注解方式调用支持
  • 主流框架的默认适配

抛出异常的方式定义资源

Sentinel中的SphU包含try-catch风格的api。用这种方式,当资源发生限流之后会抛出BlockException。这个时候可以捕捉异常,进行限流之后的逻辑处理,而我们在上面就使用了这种方式进行定义资源,关键代码如下:

// 使用限流规则监控保护资源
try (Entry entry = SphU.entry("hello")){
// 被保护的资源
return "hello sentinel";
}catch (BlockException e){
// 被限流或者降级的处理
return "系统繁忙,请稍后";
}

返回布尔值的方式定义资源

  • 定义资源保护访问

    @RestController
    public class TestBooleanController {
    @GetMapping("/boolean")
    public boolean hello(){
    if (SphO.entry("Sentinel_Boolean")){
    try {
    System.out.println("Hello Sentinel");
    return true;
    }finally {
    SphO.exit();
    }
    }else{
    // 限流降级的处理
    System.out.println("系统繁忙,请稍后");
    return false;
    }
    }

    }
  • 新增限流规则

alt
  • 查看访问结果
alt

异步调用支持方式

  • 开启异步支持

    // @EnableAsync 开启异步支持
    @EnableAsync
    @SpringBootApplication
    public class SentinelApplication {

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

    }
  • 添加异步访问方法

    新建AcyncService方法

    @Service
    public class AsyncService {
    @Async
    public void hello(){
    System.out.println("异步开始======");
    try {
    Thread.sleep(5000);
    }catch (InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("异步结束======");
    }
    }

  • 添加异步访问资源

    @RestController
    public class TestAsyncController {
    @Autowired
    AsyncService asyncService;
    @GetMapping("/async")
    public void hello(){
    AsyncEntry asyncEntry = null;
    try {
    asyncEntry = SphU.asyncEntry("Sentinel_Async");
    asyncService.hello();
    }catch (BlockException e){
    System.out.println("系统繁忙,请稍后");
    }finally {
    if (asyncEntry != null ){
    asyncEntry.exit();
    }
    }

    }

    }
  • 添加限流规则

    alt
  • 查看访问效果

alt

注解方式调用支持

  • 添加注解支持的依赖

    		<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>1.7.2</version>
    </dependency>
  • 创建Aspect配置类

    @Configuration
    public class AspectConfig {
    @Bean
    public SentinelResourceAspect sentinelResourceAspect(){
    return new SentinelResourceAspect();
    }
    }
  • 创建限流访问资源代码

    @RestController
    public class TestAnnController {
    @Autowired
    AsyncService asyncService;
    @SentinelResource(value = "Sentinel_Ann",blockHandler = "exceptionHandler")
    @GetMapping("/ann")
    public String hello(){

    return "Hello Sentinel";
    }
    public void exceptionHandler(BlockException e){
    e.printStackTrace();
    System.out.println("系统繁忙,请稍后");
    }

    }

主流框架的默认适配

为了减少开发的复杂程度,对大部分的主流框架,例如Web Servlet,Dubbo、Spring Cloud、gRPC、Spring WebFlx、Reactor等都做了适配,只需要引入对应的依赖就可以方便的整合Sentinel

SpringCloud+Sentinel

下面是整理本文时阅读的一些资料汇总,有兴趣的可以去看看

alt

版本参考地址

SpringCloud

SpringCloud Alibaba

SpringCloud Alibaba 版本对应关系

SpringCloud版本详细对应关系

Nacos-SpringCloud版本

步骤

  • springcloud 版本

     <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>Greenwich.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.1.2.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    </dependencies>
    </dependencyManagement>
  • pom 加入sentinel依赖

            <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.1.0.RELEASE</version>
    </dependency>
  • 创建限流资源代码

    @RestController
    public class TestController {
    @SentinelResource(value = "Sentinel_SpringCloud",blockHandler = "exceptionHandler")
    @GetMapping("/ann")
    public String hello(){
    return "hello sentinel";
    }
    public String exceptionHandler(BlockException e){
    e.printStackTrace();
    return "系统繁忙,请稍后";
    }
    }
  • 配置项目链接控制台

    spring.application.name=SpringCloudSentinel
    spring.cloud.sentinel.transport.dashboard=localhost:8850
  • 创建限流规则

    alt

Sentinel+Feign

  • 引入feign+sentinel的依赖

     <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.1.0.RELEASE</version>
    <exclusions>
    <exclusion>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
    <version>10.1.0</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
  • 定义服务提供类,ServiceProvider 中修改

    @EnableDiscoveryClient
    @SpringBootApplication
    public class ServerProviderApplication {

    public static void main(String[] args) {
    SpringApplication.run(ServerProviderApplication.class, args);
    }
    @Slf4j
    @RestController
    static class TestController {
    @GetMapping("/hello/{str}")
    public String hello(@PathVariable String str) {
    log.info("invoked name = " + str);
    return "hello " + str;
    }
    @GetMapping("/test")
    public String test() {
    return "hello sentinel";
    }
    }

    }
  • 增加feign客户端的支持

    @SpringBootApplication
    // 开启feign-client
    @EnableFeignClients
    public class SentinelApplication {

    public static void main(String[] args) {

    SpringApplication.run(SentinelApplication.class, args);
    }

    }
  • 定义远程调用接口

    @FeignClient(value = "alibaba-nacos-discovery-server",fallback = FallBackService.class)
    public interface FeignAgent {
    @GetMapping("/test")
    String hello();
    }

  • 定义回调降级类

    @Component
    public class FallBackService implements FeignAgent {
    @Override
    public String hello() {
    return "系统繁忙,请稍后";
    }
    }
  • 配置项目链接sentinel控制台,开始sentinel对feign的支持

    spring.application.name=SpringCloudSentinel
    spring.cloud.sentinel.transport.dashboard=localhost:8850
    # feign-sentinel 支持
    feign.sentinel.enabled=true
  • 启动注册中心nacos,服务提供者serviceProvider和sentinel客户端

  • 定义限流规则,Sentinel和Feign整合时,限流规则的编写形式为:

    http请求方式:协议://服务名/请求路径跟参数
    例:GET:http://alibaba-nacos-discovery-server/test
alt

Sentinel+SpringCloud Gateway

  • 引入依赖

     <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.2</version>
    <optional>true</optional>
    </dependency>
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.1.0.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    <version>2.1.0.RELEASE</version>
    </dependency>

  • 配置gateway信息,链接Sentinel控制台

    spring:
    application:
    name: SpringCloudGateWay
    cloud:
    gateway:
    routes:
    # id: sentinel-feign-gateway 限流时route id使用这个
    - id: sentinel-feign-gateway
    uri: lb://SpringCloudSentinel:8002
    predicates:
    # Path=/feign/** 自定义API维度限流使用
    - Path=/feign/**
    nacos:
    discovery:
    server-addr: 127.0.0.1:8848
    sentinel:
    transport:
    dashboard: 127.0.0.1:8850

    server:
    port: 8003
  • 配置限流时返回内容

    @Component
    public class GatewayConfiguration {
    @PostConstruct
    public void doInit(){
    GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
    return ServerResponse.status(200).syncBody("系统繁忙,请稍后");
    }
    });
    }
    }
  • 启用服务发现

    @EnableDiscoveryClient
    @SpringBootApplication
    public class GatewayApplication {

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

    }

限流规则配置

  • route id
alt
  • 自定义API维度
alt

流量控制实现

Sentinel的所有规则都可以在内存态中动态的查询及修改,修改之后立即生效。同时Sentinel也提供API,选择定制自己的规则策略

Sentinel主要支持以下几种规则

  • 流量控制规则
  • 熔断降级规则
  • 系统保护规则
  • 来源访问控制规则
  • 动态规则扩展

流量控制规则实现

流量控制(flow control),其原理是监控应用流量的QPS或并发线程数等指标,当达到制定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性

流量控制主要有两种方式

  • 并发线程数:并发线程数限流用于保护业务线程数不被耗尽

  • QPS:当QPS超过某个阈值的时候,则采取措施进行流量控制

一条限流规则主要由下面几个元素组成,我们可以组成这些元素来实现不同的限流效果:

  • resource:资源名,即限流的对象

  • count:限流阈值

  • grade:限流阈值类型(QPS或并发线程数)

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

  • strategy:调用关系限流策略

  • controBehavior:流量控制效果(直接拒绝,Warm Up,匀速排队)

    • 直接拒绝(RuleConstant.CONTROL_BRHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求被立即拒绝,拒绝方式为抛出 FlowException.这种方式适用与对系统处理能力确切已知的请求下,比如通过压测确定了系统的准确水位时
    • Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热,冷启动方式,当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过“冷启动”,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间。避免冷系统被压垮
    • 排队等待(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法

    同一个资源可以同时由多个限流规则,检查规则时会依次检查

熔断降级

熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自行熔断(默认行为是抛出DegradeException)

Field说明默认值
resource资源名,即限流规则的对象
count阈值
grade熔断策略,支持秒级RT/秒级异常比例/分钟级异常数秒级平均RT
timeWindow降级的时间,单位为s
reSlowRequestAmountRT模式下1秒内连续多少个请求的平均RT超出阈值方可触发熔断(1.7.0引入)5
minRequestAmount异常熔断的触发最小请求数,请求数小于该值时及时异常比率超出阈值也不会熔断(1.7.0引入)5

同一个资源可以有多个降级规则

熔断策略详解

  • 平均响应时间(DEGRADE_GRADE_RT):当1s内连续进入N个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以ms为单位),那么接下来的时间(DegradeRule 中的timeWindow,以s为单位)之内,对这个方法的调用都会自动熔断
  • 异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量>=N(可配置),并且每秒异常总数占通过量的比值超过阈值(DegradeRule中的count)之后,资源进入降级状态,即在接下的时间(DegradeRule 中的timeWindow,以s为单位)之内,对这个方法调用都会自动的返回。异常比率的阈值范围时[0.0,1.0],代表0%-100%
  • 异常数(DEGRADE_GRADE_EXCEPTION_COUNT):当资源近一分钟的异常数目超过阈值之后就会进行熔断。注意由于统计时间时分钟级别的,若timeWindow小于60s,则结束熔断状态后仍可能再进入熔断状态

熔断降级设计理念

在限制的手段上,Sentinel和Hystrix采取完全不一样的方法

Hystrix通过线程池隔离的方式,来对依赖(在Sentinel的概念中对应资源)进行了隔离,这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本(过多的线程池导致线程数目过多)还需要预先给各个资源做线程池大小的分配

Sentinel对这个问题采取了两种手段

  • 通过并发线程数进行限制

    和资源池隔离的方法不同,Sentinel通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会导致线程数的逐步累积,当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝,堆积的线程完成任务后才开始继续接收请求

  • 通过响应时间对资源进行降级

    除了对并发线程数进行控制以外,Sentinel还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复

系统自适应保护实现

Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的Load、CPU使用率、总体平均RT、入口QPS和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能的保持最大吞吐量的同时保证系统整体的稳定性

系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效,入口流量指的是进入应用的流量(EntryType.IN),比如Web服务或者Dubbo服务端接收到的请求,都属于入口流量

系统规则支持一下的模式

  • Load自适应(仅对Linux/Unix-like机器生效):系统的load1作为启发指标,进行自适应系统保护,当系统load1超过设定的启发值,且系统当前的并发线程数超过估算的系统容量是才会触发系统保护(BBR阶段).系统容量由系统的 maxQps*minRt估算得出,设定参考值一般是 CPU cores * 2.5
  • CPU usage (1.5.0版本):当系统CPU使用率超过阈值即出发系统保护(取值范围0.0-1.0)比较灵敏
  • 平均RT:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护
  • 入口QPS:当单台机器上所有入口流量的QPS达到阈值即触发系统保护

重要的属性

Field说明默认值
highestSystemLoadload1触发值,用于触发自适应控制阶段-1(不生效)
avgRt所有入口流量的平均响应时间-1(不生效)
maxThread入口l巨量的最大并发数-1(不生效)
qps所有入口资源的QPS-1(不生效)
highestCpuUsage当前系统的CPU使用率(0.0-1.0)-1(不生效)

代码控制

@RestController
public class TestLoadController {

@SentinelResource(entryType = EntryType.IN)
@GetMapping("/rule")
public String hello(){
return "hello sentinel rule";
}


// @PostConstruct
// public void initDegradeRule(){
// List<SystemRule> rules = new LinkedList<>();
// SystemRule rule = new SystemRule();
// rule.setQps(2);
// rules.add(rule);
// SystemRuleManager.loadRules(rules);
// }


}

控制台配置

系统设置

授权控制

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

重要属性

  • resource: 资源名,即限流规则的对象
  • limitApp: 请求来源,对应的黑名单/白名单,多个用“,"分割
  • strategy:限制模式,AUTHORITY_WHITE为白名单模式,AYTHORITY_BLACK为黑名单模式,默认为白名单模式

代码配置

  • 黑白名单配置
@RestController
public class WhiteBlackController {

@SentinelResource(value = "Sentinel_Rule",blockHandler = "exceptionHandler")
@GetMapping("/rule")
public String hello(){
return "hello sentinel rule";
}
public String exceptionHandler(BlockException e){
e.printStackTrace();
return "系统繁忙,请稍后";
}

@PostConstruct
public void initWhiteRules(){
List<AuthorityRule> rules = new LinkedList<>();
AuthorityRule rule = new AuthorityRule();
rule.setResource("Sentinel_Rule");
rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
rule.setLimitApp("192.168.168.168");
rules.add(rule);
AuthorityRuleManager.loadRules(rules);
}

@PostConstruct
public void initBlackRules(){
List<AuthorityRule> rules = new LinkedList<>();
AuthorityRule rule = new AuthorityRule();
rule.setResource("Sentinel_Rule");
rule.setStrategy(RuleConstant.AUTHORITY_BLACK);
rule.setLimitApp("127.0.0.1");
rules.add(rule);
AuthorityRuleManager.loadRules(rules);
}

}
  • 获取IP配置

    @Component
    public class SentinelConfig {
    @PostConstruct
    public void init(){
    WebCallbackManager.setRequestOriginParser(new RequestOriginParser() {
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
    return httpServletRequest.getRemoteAddr();
    }
    });
    }
    }

动态规则设置

拉模式拓展

实现拉模式的数据源最简单的方式是继承AutoRefreshDataSource抽象类,然后实现readSource()方法,在该方法里从指定数据源读取字符串格式的配置数据。

推模式拓展

实现推模式的数据源最简单的方式是继承 AbstractDataSource 抽象类,在其构造方法中添加监听器,并实现 readSource() 从指定数据源读取字符串格式的配置数据。比如 基于 Nacos 的数据源

推模式:使用Nacos配置规则

  • pom加入依赖

            <dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.7.1</version>
    </dependency>
  • 动态配置规则

    @Component
    public class SentinelDataSourceConfig {
    private static final String KEY = "TestResource";
    // nacos server ip
    private static final String remoteAddress = "localhost:8848";
    // nacos group
    private static final String groupId = "Sentinel_Demo";
    // nacos dataId
    private static final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
    // if change to true, should be config NACOS_NAMESPACE_ID
    private static boolean isDemoNamespace = false;
    // fill your namespace id,if you want to use namespace. for example: 0f5c7314-4983-4022-ad5a-347de1d1057d,you can get it on nacos's console
    private static final String NACOS_NAMESPACE_ID = "${namespace}";

    @PostConstruct
    private static void loadRules() {
    ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
    source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
    }));
    FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
    }

    private static void loadMyNamespaceRules() {
    Properties properties = new Properties();
    properties.put(PropertyKeyConst.SERVER_ADDR, remoteAddress);
    properties.put(PropertyKeyConst.NAMESPACE, NACOS_NAMESPACE_ID);

    ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(properties, groupId, dataId,
    source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
    }));
    FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
    }
    }
  • 发送nacos配置,或者手动创建

        public static void main(String[] args) throws Exception {
    final String remoteAddress = "localhost:8848";
    final String groupId = "Sentinel_Demo";
    final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
    final String rule = "[\n"
    + " {\n"
    + " \"resource\": \"Sentinel_SpringCloud\",\n"
    + " \"controlBehavior\": 0,\n"
    + " \"count\": 5.0,\n"
    + " \"grade\": 1,\n"
    + " \"limitApp\": \"default\",\n"
    + " \"strategy\": 0\n"
    + " }\n"
    + "]";
    ConfigService configService = NacosFactory.createConfigService(remoteAddress);
    System.out.println(configService.publishConfig(dataId, groupId, rule));
    }

行了,到这就结束了,本来打算简单整理一下,但是发现越整理越多,而且真的是没有试验一切都是刷流氓,快去写个demo体验下Sentinel的丝滑吧

alt

本文由 mdnice 多平台发布

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值