当前位置: 首页 > news >正文

【SpringCloud AlibabaSentinel实现熔断与限流】

本笔记内容为尚硅谷SpringCloud AlibabaSentinel部分 

目录

一、Sentinel

1、官网

2、Sentinel是什么

3、下载

4、特性

5、使用

二、安装Sentinel控制台 

1、sentinel组件由2部分构成

2、安装步骤

1.下载

2.运行命令

3.访问sentinel管理界面

三、初始化演示工程

四、流控规则

1、基本介绍

解释说明

2、流控模式

1.直接(默认)

2.关联

3.链路

3、流控效果

1.直接->快速失败(默认的流控处理)

2.预热

3.排队等待 

五、降级规则

1、基本介绍

2、降级策略实战

1.RT

2.异常比例

3.异常数

六、热点key限流

1、基本介绍

2、测试代码

3、配置

4、参数例外项

配置

七、系统规则 

各项配置参数说明 

八、@SentinelResource 

1、按资源名称限流+后续处理

2、按照Url地址限流+后续处理 

3、客户自定义限流处理逻辑 

4、更多注解属性说明

九、服务熔断功能 

1、Ribbon系列

2、Feign系列

3、熔断框架比较

十、规则持久化

步骤 


一、Sentinel


1、官网

https://github.com/alibaba/Sentinel

中文:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

2、Sentinel是什么

类似之前学过的Hystrix

3、下载

Releases · alibaba/Sentinel · GitHub

4、特性

5、使用

查看官网:Spring Cloud Alibaba Reference Documentation

服务使用中的各种问题

  • 服务雪崩
  • 服务降级
  • 服务熔断
  • 服务限流

二、安装Sentinel控制台 


1、sentinel组件由2部分构成

后台+前台8080

2、安装步骤

1.下载

Releases · alibaba/Sentinel · GitHub

下载到本地sentinel-dashboard-1.7.0.jar

2.运行命令

前提:java8环境正常,8080端口不能被占用

命令:java -jar sentinel-dashboard-1.7.0.jar

3.访问sentinel管理界面

http://localhost:8080,登录账号密码均为sentinel

三、初始化演示工程


1、启动Nacos8848成功

http://localhost:8848/nacos/#/login

2、Module

cloudalibaba-sentinel-service8401

3、POM

<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>cloud190805</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloudalibaba-sentinel-service8401</artifactId><dependencies><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency><!--SpringCloud ailibaba sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- SpringBoot整合Web组件+actuator --><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><!--日常通用jar包配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></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></project>

4、YML

server:port: 8401spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:#Nacos服务注册中心地址server-addr: localhost:8848sentinel:transport:#配置Sentinel dashboard地址dashboard: localhost:8080#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口port: 8719management:endpoints:web:exposure:include: '*'

5、主启动

package com.atguigu.springcloud.alibaba;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401
{public static void main(String[] args) {SpringApplication.run(MainApp8401.class, args);}
}

6、业务类FlowLimitController

package com.atguigu.springcloud.alibaba.controller;import com.atguigu.springcloud.alibaba.service.OrderService;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
public class FlowLimitController
{@GetMapping("/testA")public String testA(){return "------testA";}@GetMapping("/testB")public String testB(){return "------testB";}
}

启动Sentinel8080 cmd :java -jar sentinel-dashboard-1.7.0.jar

启动微服务8401

启动8401微服务后查看sentienl控制台,发现什么都没有

Sentinel采用的懒加载说明

执行一次访问即可(http://localhost:8401/testA 和 http://localhost:8401/testB)

效果

结论:sentinel8080正在监控微服务8401

四、流控规则


1、基本介绍

解释说明

2、流控模式

1.直接(默认)

直接->快速失败(系统默认)

配置及说明

2.关联

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

当与A关联的资源B达到阀值后,就限流A自己、B惹事,A挂了

配置A

postman模拟并发密集访问testB

访问testB成功

postman里新建多线程集合组

将访问地址添加进新新线程组

Run(大批量线程高并发访问B,导致A失效了)

运行后发现testA挂了,点击访问http://localhost:8401/testA,结果Blocked by Sentinel (flow limiting)

3.链路

多个请求调用了同一个微服务(可以想象当作VIP通道)

3、流控效果

1.直接->快速失败(默认的流控处理)

2.预热

公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值

官网:流量控制 · alibaba/Sentinel Wiki · GitHub

默认coldFactor为3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

限流 冷启动:限流 冷启动 · alibaba/Sentinel Wiki · GitHub

WarmUp配置

多次点击http://localhost:8401/testB、刚开始不行,后续慢慢OK

应用场景

如:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值。

3.排队等待 

官网:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

测试

五、降级规则


官网:熔断降级 · alibaba/Sentinel Wiki · GitHub

1、基本介绍

RT(平均响应时间,秒级)

      平均响应时间   超出阈值  且   在时间窗口内通过的请求>=5,两个条件同时满足后触发降级

      窗口期过后关闭断路器

      RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)

 

异常比列(秒级)

    QPS >= 5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

 

异常数(分钟级)

     异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。

当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

Sentinel的断路器是没有半开状态的

半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。具体可以参考Hystrix

2、降级策略实战

1.RT

 

测试

@GetMapping("/testD")
public String testD()
{//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }log.info("testD 测试RT");return "------testD";
}

配置

jmeter压测

结论:

永远一秒钟打进来10个线程(大于5个了)调用testD,我们希望200毫秒处理完本次任务,

如果超过200毫秒还没处理完,在未来1秒钟的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电了

后续我停止jmeter,没有这么大的访问量了,断路器关闭(保险丝恢复),微服务恢复OK

2.异常比例

测试

@GetMapping("/testD")
public String testD()
{log.info("testD 测试RT");int age = 10/0;return "------testD";
}

配置

jmeter

结论

3.异常数

异常数是按照分钟统计的

测试

@GetMapping("/testE")
public String testE()
{log.info("testE 测试异常比例");int age = 10/0;return "------testE 测试异常比例";
}

配置

jmeter

六、热点key限流


1、基本介绍

官网:https://github.com/alibaba/Sentinel/wiki/热点参数限流

2、测试代码

@SentinelResource

@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "dealHandler_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1, @RequestParam(value = "p2",required = false) String p2){return "------testHotKey";
}
public String dealHandler_testHotKey(String p1,String p2,BlockException exception)
{return "-----dealHandler_testHotKey";
}

3、配置

限流模式只支持QPS模式,固定写死了。(这才叫热点)

@SentinelResource注解的方法参数索引,0代表第一个参数,1代表第二个参数,以此类推

单机阀值以及统计窗口时长表示在此窗口时间超过阀值就限流。

上面的抓图就是第一个参数有值的话,1秒的QPS为1,超过就限流,限流后调用dealHandler_testHotKey支持方法。

测试

4、参数例外项

上述案例演示了第一个参数p1,当QPS超过1秒1次点击后马上被限流

配置

 

@SentinelResource

处理的是Sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理;

 

RuntimeException

int age = 10/0,这个是java运行时报出的运行时异常RunTimeException,@SentinelResource不管

总结

 @SentinelResource主管配置出错,运行出错该走异常走异常

七、系统规则 


官网:系统自适应限流 · alibaba/Sentinel Wiki · GitHub

各项配置参数说明 

八、@SentinelResource 


1、按资源名称限流+后续处理

启动Nacos成功:http://localhost:8848/nacos/#/login

启动Sentinel成功:java -jar sentinel-dashboard-1.7.0.jar

Module

1.新建cloudalibaba-sentinel-service8401

2.POM

<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>mscloud03</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloudalibaba-sentinel-service8401</artifactId><dependencies><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到--><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId></dependency><!--SpringCloud ailibaba sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- SpringBoot整合Web组件+actuator --><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><!--日常通用jar包配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></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></project>

3.YML

server:port: 8401spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard地址port: 8719management:endpoints:web:exposure:include: '*'

4.业务类RateLimitController

package com.atguigu.springcloud.alibaba.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@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 服务不可用");}
}

5.主启动

package com.atguigu.springcloud.alibaba;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401
{public static void main(String[] args) {SpringApplication.run(MainApp8401.class, args);}
}

配置流控规则

图形配置和代码关系(表示1秒钟内查询次数大于1,就跑到我们自定义的处流,限流)

额外问题:此时关闭问服务8401看看,Sentinel控制台,流控规则消失了-临时(见第十的规则持久化)

2、按照Url地址限流+后续处理 

通过访问的URL来限流,会返回Sentinel自带默认的限流处理信息

业务类RateLimitController

package com.atguigu.springcloud.alibaba.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@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 服务不可用");}@GetMapping("/rateLimit/byUrl")@SentinelResource(value = "byUrl")public CommonResult byUrl(){return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));}
}

访问:http://localhost:8401/rateLimit/byUrl

Sentinel控制台配置 

上面兜底方案面临的问题

  1. 系统默认的,没有体现我们自己的业务要求。
  2. 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。
  3. 每个业务方法都添加一个兜底的,那代码膨胀加剧。
  4. 全局统一的处理方法没有体现。

3、客户自定义限流处理逻辑 

创建CustomerBlockHandler类用于自定义限流处理逻辑

1.自定义限流处理类CustomerBlockHandler

package com.atguigu.springcloud.alibaba.myhandler;import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.alibaba.entities.CommonResult;
import org.springframework.stereotype.Component;public class CustomerBlockHandler
{public static CommonResult handleException(BlockException exception){return new CommonResult(2020,"自定义的限流处理信息......CustomerBlockHandler");}
}

2.RateLimitController

启动微服务后先调用一次http://localhost:8401/rateLimit/customerBlockHandler

3.Sentinel控制台配置 

测试后我们自定义的出来了

4、更多注解属性说明

 

九、服务熔断功能 


sentinel整合ribbon+openFeign+fallback

1、Ribbon系列

1.启动nacos和sentinel

2.提供者9003/9004

新建cloudalibaba-provider-payment9003/9004两个一样的做法

POM

<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>mscloud03</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloudalibaba-provider-payment9003</artifactId><dependencies><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></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>
</project>

YML(记得修改不同的端口号)

server:port: 9003spring:application:name: nacos-payment-providercloud:nacos:discovery:server-addr: localhost:8848 #配置Nacos地址management:endpoints:web:exposure:include: '*'

主启动

package com.atguigu.springcloud.alibaba;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9003
{public static void main(String[] args) {SpringApplication.run(PaymentMain9003.class, args);}
}

业务类

package com.atguigu.springcloud.alibaba.controller;import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
@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;}}

测试地址:http://localhost:9003/paymentSQL/1

3.消费者84

新建cloudalibaba-consumer-nacos-order84

POM

<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>mscloud03</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloudalibaba-consumer-nacos-order84</artifactId><dependencies><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--SpringCloud ailibaba sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></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>
</project>

YML

server:port: 84spring:application:name: nacos-order-consumercloud:nacos:discovery:server-addr: localhost:8848sentinel:transport:#配置Sentinel dashboard地址dashboard: localhost:8080#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口port: 8719#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者)
service-url:nacos-user-service: http://nacos-payment-provider

主启动

package com.atguigu.springcloud.alibaba;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient
@SpringBootApplication
public class OrderNacosMain84
{public static void main(String[] args) {SpringApplication.run(OrderNacosMain84.class, args);}
}

业务类

ApplicationContextConfig

package com.atguigu.springcloud.alibaba.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class ApplicationContextConfig
{@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}

CircleBreakerController​

 

fallback和blockHandler都配置

编码

package com.atguigu.springcloud.alibaba.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.concurrent.Executors;@RestController
@Slf4j
public class CircleBreakerController
{public static final String SERVICE_URL = "http://nacos-payment-provider";@Resourceprivate RestTemplate restTemplate;@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 ("非法参数异常....");}else if (result.getData() == null) {throw new NullPointerException ("NullPointerException,该ID没有对应记录");}return result;}public CommonResult handlerFallback(@PathVariable  Long id,Throwable e) {Payment payment = new Payment(id,"null");return new CommonResult<>(444,"fallback,无此流水,exception  "+e.getMessage(),payment);}public CommonResult blockHandler(@PathVariable  Long id,BlockException blockException) {Payment payment = new Payment(id,"null");return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);}}

sentinel需配置

结果 

忽略属性

程序异常打到前台了,对用户不友好 

2、Feign系列

2.POM

<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>mscloud03</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloudalibaba-consumer-nacos-order84</artifactId><dependencies><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--SpringCloud ailibaba sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!--SpringCloud openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!-- SpringBoot整合Web组件 --><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><!--日常通用jar包配置--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></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>
</project>

3.YML(激活Sentinel对Feign的支持)

server:port: 84spring:application:name: nacos-order-consumercloud:nacos:discovery:#Nacos服务注册中心地址server-addr: localhost:8848sentinel:transport:#配置Sentinel dashboard地址dashboard: localhost:8080#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口port: 8719management:endpoints:web:exposure:include: '*'
# 激活Sentinel对Feign的支持
feign:sentinel:enabled: true  

4.业务类

带@FeignClient注解的业务接口(定义接口)

package com.atguigu.springcloud.alibaba.service;import com.atguigu.springcloud.alibaba.entities.CommonResult;
import com.atguigu.springcloud.alibaba.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/*** 使用 fallback 方式是无法获取异常信息的,* 如果想要获取异常信息,可以使用 fallbackFactory参数*/
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)//调用中关闭9003服务提供者
public interface PaymentService
{@GetMapping(value = "/paymentSQL/{id}")public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}

fallback = PaymentFallbackService.class(实现类)

package com.atguigu.springcloud.alibaba.service;import com.atguigu.springcloud.alibaba.entities.CommonResult;
import com.atguigu.springcloud.alibaba.entities.Payment;
import org.springframework.stereotype.Component;@Component
public class PaymentFallbackService implements PaymentService
{@Overridepublic CommonResult<Payment> paymentSQL(Long id){return new CommonResult<>(444,"服务降级返回,没有该流水信息",new Payment(id, "errorSerial......"));}
}

5.Controller

package com.atguigu.springcloud.alibaba.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;@RestController
@Slf4j
public class CircleBreakerController
{public static final String SERVICE_URL = "http://nacos-payment-provider";@Resourceprivate RestTemplate restTemplate;@RequestMapping("/consumer/fallback/{id}")//@SentinelResource(value = "fallback") //没有配置//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规@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;}//本例是fallbackpublic CommonResult handlerFallback(@PathVariable  Long id,Throwable e) {Payment payment = new Payment(id,"null");return new CommonResult<>(444,"兜底异常handlerFallback,exception内容  "+e.getMessage(),payment);}//本例是blockHandlerpublic CommonResult blockHandler(@PathVariable  Long id,BlockException blockException) {Payment payment = new Payment(id,"null");return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException  "+blockException.getMessage(),payment);}//==================OpenFeign@Resourceprivate PaymentService paymentService;@GetMapping(value = "/consumer/openfeign/{id}")public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){if(id == 4){throw new RuntimeException("没有该id");}return paymentService.paymentSQL(id);}}

6.主启动

添加@EnableFeignClients启动Feign的功能

package com.atguigu.springcloud.alibaba;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class OrderNacosMain84
{public static void main(String[] args) {SpringApplication.run(OrderNacosMain84.class, args);}
}

3、熔断框架比较

十、规则持久化


一旦我们重启应用,sentinel规则将消失,生产环境需要将配置规则进行持久化

将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel上的流控规则持续有效

步骤 

1.修改cloudalibaba-sentinel-service8401

2.POM引入持久化依赖

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

3.YML

添加Nacos数据源配置

server:port: 8401spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址sentinel:transport:dashboard: localhost:8080 #配置Sentinel dashboard地址port: 8719datasource:ds1:nacos:server-addr: localhost:8848dataId: cloudalibaba-sentinel-servicegroupId: DEFAULT_GROUPdata-type: jsonrule-type: flowmanagement:endpoints:web:exposure:include: '*'feign:sentinel:enabled: true # 激活Sentinel对Feign的支持

4.添加Nacos业务规则配置

5.启动8401后刷新sentinel发现业务规则有了

6.快速访问测试接口

7.停止8401再看sentinel

 结束!

相关文章:

【SpringCloud AlibabaSentinel实现熔断与限流】

本笔记内容为尚硅谷SpringCloud AlibabaSentinel部分 目录 一、Sentinel 1、官网 2、Sentinel是什么 3、下载 4、特性 5、使用 二、安装Sentinel控制台 1、sentinel组件由2部分构成 2、安装步骤 1.下载 2.运行命令 3.访问sentinel管理界面 三、初始化演示工程 …...

类与对象-封装

一、封装的意义封装是C面向对象三大特性之一语法&#xff1a; class name { 访问权限:属性行为 };注意&#xff1a;类中的属性和行为 统称为成员属性 又称 成员属性 / 成员变量行为 又称 成员函数 / 成员方法封装将属性和行为作为一个整体&#xff0c;表现生活中的事物例①&…...

【回忆杀】2012年拥有第一台电脑【致逝去的青春】

高中说起 在2012年的时候吧&#xff0c;高考过后&#xff0c;那个时候一门心思的想当一名体育老师【现在居然还有这个想法&#xff0c;哈哈】&#xff0c;最后没有考上自己希望的大学我记得好像是2012年7月的时候就去重庆投靠朋友&#xff0c;他教我做模具&#xff0c;2012年做…...

PointNeXt: Revisiting PointNet++ with Improved Training and Scaling Strategies

Abstract PointNet 是点云理解领域最有影响力的神经网络架构之一。虽然近期出现了 PointMLP 和 Point Transformer 等新型网络&#xff0c;它们的精度已经大大超过了 PointNet&#xff0c;但我们发现大部分性能提升是由于改进的训练策略&#xff0c;例如数据增强和优化技术以及…...

打印九九乘法表-课后程序(JavaScript前端开发案例教程-黑马程序员编著-第2章-课后作业)

【案例2-9】打印九九乘法表 一、案例描述 考核知识点 for双重循环 练习目标 掌握for循环应用。实现九九乘法表。 需求分析 九九乘法表相信大家一点也不陌生&#xff0c;之前见到的乘法表是印刷在课程本之上的。而在本案例中我们将用JavaScript代码来实现九九乘法表。 案例分…...

【Linux】基于阻塞队列的生产者消费者模型

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;为何要使用…...

【华为OD机试 2023最新 】 真正的密码(C++)

文章目录 题目描述输入描述输出描述用例题目解析C++题目描述 在一行中输入一个字符串数组,如果其中一个字符串的所有以索引0开头的子串在数组中都有,那么这个字符串就是潜在密码, 在所有潜在密码中最长的是真正的密码,如果有多个长度相同的真正的密码,那么取字典序最大的…...

差分算法(蓝桥杯复习+例题讲解+模板c++)

文章目录差分介绍差分应用区间加区间求和总结3729. 改变数组元素100. 增减序列文章首发于&#xff1a;My Blog 欢迎大佬们前来逛逛 差分介绍 差分是一种常见的算法&#xff0c;用于快速修改数组中某一段区间的值。 差分的思想就是预处理出数组的差分数组&#xff0c;然后修改…...

CSS+ JS 实现手电筒效果

前言概述 JavaScript 结合 CSS 打造的一款图片特效&#xff0c;当鼠标拖拽滑块时&#xff0c;让本该置灰的图片局部恢复本来的颜色。且该效果随着你的鼠标的按下时的移动而移动。 核心功能 图片置灰 拖拽功能 让滑块位置处的图片恢复本来的颜色 实现原理 这个的实现原理并不…...

2021地理设计组二等奖:基于InSAR和指数分析的地面沉降风

作品简介 一、作品背景 地面沉降是指地面高程的降低, 又称地面下沉或地沉, 是以缓慢、难以察觉的向下垂直运动为主, 是指在自然和人为因素作用下, 由于地壳表层土体压缩而导致区域性地面标高降低的一种环境现象。目前, 地面沉降己成为城市化进程中普遍存在的生态环境问题, 成为…...

计算机操作系统(第四版)第二章进程的描述与控制—课后习题答案

1.什么是前趋图&#xff1f;为什么要引入前趋图&#xff1f; 前趋图是一个有向无循环图&#xff0c;记为DAG&#xff0c;用于描述进程之间执行的先后关系。 2.试画出下面四条语句的前趋图&#xff1a; S1:axy; S2:bz1; S3:ca-b; S4:wc1; 3.为什么程序并发执行会产生间断性特征&…...

CAN通信----电路图

CAN通信----基本原理 一、CAN总线网络连接 1.闭环总线网络----ISO11898 闭环总线网络高速、短距离&#xff0c;它的总线最大长度为 40m&#xff0c;通信速度最高为 1Mbps&#xff0c;总线的两端各要求有一个120 欧的电阻。 2.开环总线网络----ISO11519 开环总线网络低速、…...

Windows系统安装ElasticSearch(一)

一 ES介绍Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单&#xff0c;它不仅包括了全文搜索功能&#xff0c;还可以进行以下工作:分布式实时文件存储&#…...

linux 产生随机数 并遍历

1、产生随机数 varRANDOMvarRANDOM varRANDOMvar[ $var % 150 ] 2、产生不重复的随机数 $ entries($(shuf -i 0-149 -n 15)) $ echo “${entries[]}” 3、对随机数排序 $ entries($(shuf -i 0-149 -n 15 | sort -n)) $ echo “entries[]"12224549546678798393118119124140…...

【3.24】Mybatis常见面试题

Mybatis常见面试题 #{}和&#xffe5;{}的区别是什么&#xff1f; 【#】&#xff1a;底层执行SQL使用PreparedStatement对象&#xff0c;预编译SQL&#xff0c;相对安全。入参使用占位符的方式。 【$】&#xff1a;底层执行SQL使用Statement对象&#xff0c;入参使用SQL拼接的…...

IDEA 热部署,修改代码不用重启项目

热部署指在修改项目代码的时候不重启服务器让修改生效。安装JRebel and XRebelFile->Settings&#xff0c;然后Plugins-> Marketplace&#xff0c;输入JRebel&#xff0c;安装如下插件——JRebel and XRebel &#xff0c;重启idea激活JRebel and XRebel第一行输入网址&am…...

将 XLS 转换为 EXE:xlCompiler Crack

只需单击几下即可将Excel文件转换为应用程序 xl编译器无需编程即可将您的Excel电子表格转换为软件应用程序 将 XLS 转换为 EXE 将Excel文件转换为具有保护选项的应用程序。Excel 到 EXE 转换器为您提供了分发 Excel 模型的竞争优势和灵活性。将 Excel 的功能丰富的环境保存在应…...

【百面成神】spring基础12问,你能坚持到第几问

前 言 &#x1f349; 作者简介&#xff1a;半旧518&#xff0c;长跑型选手&#xff0c;立志坚持写10年博客&#xff0c;专注于java后端 ☕专栏简介&#xff1a;java面试宝典&#xff0c;特点&#xff1a;全、精、深、简&#xff0c;力求每个核心知识点1分钟回答好。 &#x1f3…...

javaSE类和对象(下)

目录君1.封装2.访问限定符3.包的定义及使用4.static成员变量5.static成员方法6.代码块及其分类实例代码块静态代码块静态代码块与实例代码块的执行顺序static成员变量(类变量)初始化1.封装 面向对象程序三大特性&#xff1a;封装、继承、多态。而类和对象阶段&#xff0c;主要…...

【数据结构】第四站:单链表力扣题(二)

目录 一、链表的回文结构 二、相交链表 三、环形链表 四、环形链表Ⅱ 五、复制带随机指针的链表 一、链表的回文结构 题目描述&#xff1a;链表的回文结构_牛客题霸_牛客网 对于这道题&#xff0c;如果没有前面的一些题的基础&#xff0c;是非常难做的&#xff0c;我们的思…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...