1. sentinel

分布式系统的流量防卫兵。
以流量为切入点,从流量控制、熔断降级、系统负载保护等多个纬度保护服务的稳定性。

1.1 特征

  • 丰富的应用场景:秒杀、消息削峰填谷、集群流量控制、事实熔断下游不可应用等。
  • 完备的实时监控:可以在控制台中看到接入应用的单台机器秒级数据。
  • 广泛的开源生态:提供开箱即用的与其他开源框架/库的整合,与Spring Cloud、Dubbo、等,只需要接入相应依赖并简单的配置就可以;
  • 完善的SPI扩展点:可以通过扩展接口来快速的定制逻辑。

java熔断降级 java限流熔断_java

  • 作用:
  1. 防止服务雪崩;
  2. 服务降级;
  3. 服务熔断;
  4. 服务限流。

1.2 安装

1.3 微服务搭建

  • 新建moudule:cloudalibaba-sentinel-service8401
  • 依赖:
<dependencies>
    
		<dependency>
        	<groupId>org.example</groupId>
        	<artifactId>cloud-api-commons</artifactId>
        	<version>1.0-SNAPSHOT</version>
    	</dependency>
    	
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

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

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

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

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

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

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.3</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>
  • 配置文件:
server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719

management:
  endpoints:
    web:
      exposure:
        include: '*'
  • 启动类:
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelMain8401 {
    public static void main(String[] args) {
        SpringApplication.run(SentinelMain8401.class,args);
    }
}
  • controller:
@Slf4j
@RestController
public class FlowLimitController {
    
    @GetMapping("/testA")
    public String testA() {
        return "------testA";
    }

    @GetMapping("/testB")
    public String testB() {
        return "------testB";
    }

}
  • 启动之后,由于sentinel是懒加载机制,必须执行一次当前微服务的访问:http://localhost:8401/testA,才可以看到:
  • java熔断降级 java限流熔断_java熔断降级_03

1.4 流量控制

1.4.1 QPS——直接快速失败

QPS:达到设置的每秒请求数,进行限流;直接:api达到限流条件时,直接限流;快速失败:直接抛出异常。

  • /testA新增如下流控规则:
  • 连续请求两次接口:直接被拦截

1.4.2 线程数——直接失败

线程数:当调用该API的线程数达到阈值时,进行限流;直接:api达到限流条件时,直接限流。
即针对一个请求设置对应数量的线程进行处理,如果当前线程来不及处理请求时才会抛出异常。

java熔断降级 java限流熔断_spring cloud_04

1.4.3 关联

关联:当关联的资源达到阈值时,限流自己。

例如,这里如果/testB超过设置的阈值,就会对/testA进行访问限制。

java熔断降级 java限流熔断_限流_05

1.4.4 预热(Warm up)

预热方式,当系统长期处于低水位的情况,当流量突然激增时,直接把系统拉升到高水位可能瞬间把系统压垮。
通过冷启动,让通过的流量缓慢增加,在一定时间内增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

默认的冷加载因子是3,在设定的预热时长内最多承受阈值10/3的QPS,当超过预热时长(5秒)后可以达到最大阈值。

java熔断降级 java限流熔断_java_06

1.4.4 排队等待

匀速排队,让请求以均匀的速度通过,阈值只能是QPS类型。
主要用于处理间歇性突发的流量。

如果超过当前设置的阈值(1),则等待20000毫秒。

java熔断降级 java限流熔断_限流_07

1.4 熔断降级

熔断降级会在调用链路中某个资源出现部稳定时,对资源的调用进行限制,让请求快速失败,避免影响到其它资源而导致级联错误。
当资源被降级后,在接下来的降级时间窗口内,对该资源的调用都自动熔断。

  • 降级规则:
  1. RT(秒级):平均响应时间,只有时间窗口内通过的请求大于等于5且超出阈值同时触发,才会触发降级。
  2. 异常比例(秒级):QPS>= 5超过阈值时,触发降级,时间窗口结束后,关闭降级。
  3. 异常数(分支级):当异常数超过于阈值时,触发降级,时间窗口结束后,关闭降级。

不存在半开状态,只有开和关。

java熔断降级 java限流熔断_java_08

1.4.1 RT

  • 断开方式:
  • java熔断降级 java限流熔断_java熔断降级_09

  • 修改代码:这里让/testB睡2秒。
@GetMapping("/testB")
    public String testB() {
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "------testB";
    }
  • 配置RT:如果一秒钟进来的请求大于等于5,且都超过了设置的处理时间RT,那么在未来的1秒的窗口时间内,断路器会自动打开,当前微服务不可用。
  • java熔断降级 java限流熔断_java熔断降级_10

  • 通过压力测试之后,在访问就会发现异常。
  • java熔断降级 java限流熔断_微服务_11

1.4.2 异常比例

当请求每秒超过或等于5个,并且每秒的异常总数占通过量的比例阈值,就会熔断,在下面的窗口期中,微服务无法进行调用。

  • 断开方式:
  • java熔断降级 java限流熔断_java熔断降级_12

  • 修改代码:
@GetMapping("/testB")
    public String testB() {
        int a = 10/0;
        return "------testB";
    }
  • 配置:异常比例∈[0.0,1.0];
  • java熔断降级 java限流熔断_限流_13

1.4.3 异常数

当资源近一分钟异常数目超过阈值后会自动进行熔断。需要注意的是创窗口时间需要大于60s,否则状态结束后可能仍然处于熔断状态。

  • 断开方式:
  • 配置:

1.5 热点参数限流

很多时候会统计某个热点数据访问频次最高的前几个数据,并进行访问限制。
热点参数限流会统计传入的参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

  • 在controller中新建方法:
/**
     * 热点key测试代码
     * @param p1
     * @param p2
     * @return
     */
    @GetMapping("/hot")
    @SentinelResource(value = "hot",blockHandler = "deal_hot") // 不符合配置的热点规则,由deal_hot处理
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2){
        return "hotKey" + p1 + p2;
    }

    /**
     * testHotKey 的 blockHandler
     * @param p1
     * @param p2
     * @param e
     * @return
     */
    public String deal_hot(String p1, String p2, BlockException e){
        return "deal_hot -> blockHandler" + p1 + p2;
    }
  • 在sentinel配置热点规则:
  • java熔断降级 java限流熔断_微服务_14

  • 访问测试:当携带第一个参数(p1)的QPS超过1,就会执行blockHandler方法。
  • java熔断降级 java限流熔断_微服务_15

  • 如果不指定fallback方法,会直接在页面抛出异常。
  • 参数例外项:指定特殊指时的限流规则与平常限流规则不同。
    例如这里,当p1 == 1时,它的阈值为500
  • java熔断降级 java限流熔断_限流_16

1.6 系统规则

Sentinel系统自适应限流从整体维度对应用入口流量进行控制。

  • 系统规则模式:
  1. Load自适应:仅对Linux/Unix-like生效,进行自适应的系统保护;
  2. CPU:当前系统CPU使用率超过阈值即触发保护系统(取值[0.0,1.0]);
  3. RT:单台机器上所有入口流量的平均RT达到阈值时即触发保护系统,单位毫秒;
  4. 并发线程数:单台机器上所有入口流量的并发线程数达到阈值时即触发保护系统;
  5. 入口QPS:单台机器上所有入口流量的QPS达到阈值时即触发保护系统。

java熔断降级 java限流熔断_spring cloud_17

但是用起来很危险,比如更细粒度的划分。

1.7 @SentinelResource

  • 新建一个RateLimitController
@RestController
public class RateLimitController {
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource", blockHandler = "handleException")
    public CommonResult byResource() {
        return new CommonResult(200, "按资源名称限流测试OK", new Payment(2020L, "serial001"));
    }

    public CommonResult handleException(BlockException exception) {
        return new CommonResult(444, exception.getClass().getCanonicalName() + "\t 服务不可用");
    }	
}

1.7.1 按资源名称配置限流规则

  • 新建流控规则:
  • 测试:超过阈值执行blockHandler的方法

1.7.2 按URL地址配置限流规则

  • RateLimitController中新增方法:
@GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl() {
        return new CommonResult(200, "按url限流测试OK", new Payment(2020L, "serial002"));
    }
  • 配置流控规则:
  • 访问测试:由于未指定blockHandler,就会执行系统默认的。

1.7.3 自定义限流处理逻辑

上方处理方式,仍然存在代码耦合和代码膨胀问题,且没有全局统一处理方式。

  • 创建CustomerBlockHandler 用于自定义处理限流逻辑
public class CustomerBlockHandler {
    public static CommonResult handlerException(BlockException exception) {
        return new CommonResult(4444, "按客戶自定义,global handlerException----1");
    }


    public static CommonResult handlerException2(BlockException exception) {
        return new CommonResult(4444, "按客戶自定义,global handlerException----2");
    }
}
  • RateLimitController新增方法:
@GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException2")
    public CommonResult customerBlockHandler() {
        return new CommonResult(200, "按客戶自定义", new Payment(2020L, "serial003"));
    }
  • 配置流控规则:
  • 测试:超过阈值执行CustomerBlockHandler.handlerException2()

1.8 整合Ribbon

让消费者84通过ribbon实现负载均衡调用9003和9004微服务。

java熔断降级 java限流熔断_java熔断降级_18

1.8.1 新建服务提供者微服务

  • 新建cloudalibaba-provider-payment9004cloudalibaba-provider-payment9005
  • 依赖:
<dependencies>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <dependency>
            <groupId>org.example</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

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

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>
  • 配置:记得修改9005端口
server:
  port: 9004

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'
  • 启动类:记得修改9005类名
@SpringBootApplication
@EnableDiscoveryClient
public class NacosMain9004 {
    public static void main(String[] args) {
        SpringApplication.run(NacosMain9004.class,args);
    }
}
  • 业务类:
@RestController
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    public static HashMap<Long, Payment> hashMap = new HashMap<>();

    static {
        hashMap.put(1L, new Payment(1L, "28a8c1e3bc2742d8848569891fb42181"));
        hashMap.put(2L, new Payment(2L, "bba8c1e3bc2742d8848569891ac32182"));
        hashMap.put(3L, new Payment(3L, "6ua8c1e3bc2742d8848569891xt92183"));
    }

    @GetMapping(value = "/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
        Payment payment = hashMap.get(id);
        CommonResult<Payment> result = new CommonResult(200, "from mysql,serverPort:  " + serverPort, payment);
        return result;
    }

}
  • 访问测试:

1.8.2 新建服务消费者微服务

  • 新建module:cloudalibaba-consumer-nacos-order84
  • 依赖:
<dependencies>

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

        <dependency>
            <groupId>org.example</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </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-web</artifactId>
        </dependency>

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


        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>
  • 配置文件:
server:
  port: 84

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: localhost:8080
        #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719

#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

# 激活Sentinel对Feign的支持
feign:
  sentinel:
    enabled: true
  • 主启动类:
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class NacosOrderMain84 {
    public static void main(String[] args) {
        SpringApplication.run(NacosOrderMain84.class, args);
    }
}
  • 配置RestTmplate:
@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}
  • 业务类:
@RestController
@Slf4j
public class CircleBreakerController {
    public static final String SERVICE_URL = "http://nacos-payment-provider";

    @Resource
    private RestTemplate restTemplate;

    @RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback") //没有配置
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }
}
  • 访问:可以实现轮询

1.8.3 未配置fallback

  • 如下代码:没有指定配置fallback,
@RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback") //没有配置
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }
  • 访问http://localhost:84/consumer/fallback/4:可以发现没有任何处理。

1.8.4 只配置fallback

  • 如下代码,指定fallback为handlerFallback()
@RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }

    //本例是fallback
    public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
        Payment payment = new Payment(id, "null");
        return new CommonResult<>(444, "兜底异常handlerFallback,exception内容  " + e.getMessage(), payment);
    }
  • 重启84端口后,访问http://localhost:84/consumer/fallback/4,出现自定义的fallback。

1.8.5 只配置blackHandler

  • 代码如下:
@RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }

    //本例是blockHandler
    public CommonResult blockHandler(@PathVariable Long id, BlockException blockException) {
        Payment payment = new Payment(id, "null");
        return new CommonResult<>(445, "blockHandler-sentinel限流,无此流水: blockException  " + blockException.getMessage(), payment);
    }
}
  • 重启84端口后,访问http://localhost:84/consumer/fallback/4,可以看出blockHandlersentinel控制台配置违规。

1.8.5 配置blackHandler和fallback

  • 代码如下:
@RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler")
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }

    //本例是fallback
    public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
        Payment payment = new Payment(id, "null");
        return new CommonResult<>(444, "兜底异常handlerFallback,exception内容  " + e.getMessage(), payment);
    }

    //本例是blockHandler
    public CommonResult blockHandler(@PathVariable Long id, BlockException blockException) {
        Payment payment = new Payment(id, "null");
        return new CommonResult<>(445, "blockHandler-sentinel限流,无此流水: blockException  " + blockException.getMessage(), payment);
    }
  • 重启后,访问http://localhost:84/consumer/fallback/4测试:
  • 配置流控规则:
  • 超出阈值,再访问http://localhost:84/consumer/fallback/1测试:
  • 超出阈值再访问http://localhost:84/consumer/fallback/4,测试:
  • 可以看出,被限流降级后会由blockHandler来处理。

1.8.6 异常忽略属性

  • 代码如下:
@RequestMapping("/consumer/fallback/{id}")
    @SentinelResource(value = "fallback",
            fallback = "handlerFallback",
            blockHandler = "blockHandler",
            exceptionsToIgnore = {IllegalArgumentException.class})
    public CommonResult<Payment> fallback(@PathVariable Long id) {
        CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id);

        if (id == 4) {
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常....");
        } else if (result.getData() == null) {
            throw new NullPointerException("NullPointerException,该ID没有对应记录,空指针异常");
        }

        return result;
    }

    //本例是fallback
    public CommonResult handlerFallback(@PathVariable Long id, Throwable e) {
        Payment payment = new Payment(id, "null");
        return new CommonResult<>(444, "兜底异常handlerFallback,exception内容  " + e.getMessage(), payment);
    }

    //本例是blockHandler
    public CommonResult blockHandler(@PathVariable Long id, BlockException blockException) {
        Payment payment = new Payment(id, "null");
        return new CommonResult<>(445, "blockHandler-sentinel限流,无此流水: blockException  " + blockException.getMessage(), payment);
    }
  • 也就是说如果当前方法抛出IllegalArgumentException异常,就不会由fallback来处理,但如果限流时仍然会走blockHandler

1.9 整合OpenFeign

  • 新建接口:
@FeignClient(value = "nacos-payment-provider", fallback = PaymentFallbackService.class)
public interface PaymentService {
    @GetMapping(value = "/paymentSQL/{id}")
    CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
  • fallback实现类:
@Component
public class PaymentFallbackService implements PaymentService {
    @Override
    public CommonResult<Payment> paymentSQL(Long id) {
        return new CommonResult<>(44444, "服务降级返回,---PaymentFallbackService", new Payment(id, "errorSerial"));
    }
}
  • 新增controller:
@Slf4j
@RestController
public class MyFeignController {
    @Resource
    private PaymentService paymentService;

    @GetMapping(value = "/consumer/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) {
        return paymentService.paymentSQL(id);
    }
}
  • 启动84,访问:http://localhost:84/consumer/paymentSQL/4,可以访问成功。
  • 模拟服务提供者宕机,看84会不会自动关闭调用:测试成功。

1.10 sentinel持久化

由于默认的流控规则等,都是临时的,重启之后就消失。需要将配置的规则存入持久化容器中。

  • 将配置持久化到nacos中,只要nacos中的配置不删除,针对当前微服务配置的sentinel中的规则都不会删除。
  • 这里以8401为例
  • 新增依赖:
<dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
  • 修改配置文件:
server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: 49.232.141.194:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
      datasource:
        ds1: # 将当前微服务的sentinel配置存入到nacos持久化
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

management:
  endpoints:
    web:
      exposure:
        include: '*'
  • 在nacos中新增配置:
  • json内容:
[
    {
	    "resource": "/rateLimit/byUrl",
	    "limitApp": "default",
	    "grade": 1,
	    "count": 1,
	    "strategy": 0,
	    "controlBehavior": 0,
	    "clusterMode": false
    }
]
  • 启动8401,在sentinel中可以看到配置的规则。