Sentinel降级服务

news/2024/11/18 8:35:44/

Sentinel降级简介

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

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

image-20201105132234324

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

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

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

异常比例(秒级)

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

异常数

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

Sentinel降级-RT

修改子项目(8401)的FlowLimitController

@GetMapping("/testD")public String testD() {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}return "**********testD***********";}

在sentinel的窗口,设置降级

image-20201106093629292

当一秒钟打进来十个线程来调用testD,我们希望200毫秒处理完本次任务,如果超过200毫秒还没处理完,在未来1秒钟的时间窗口内,断路器打开,服务不可用。

Sentinel降级-异常比例

异常比例:当资源的每秒请求量>=5,并且每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,即在接下来的时间窗口之内,对这个方法的调用都会自动返回,异常比例的阈值范围[0.0,1.0],代表0%-100%。

修改子项目(8401)的FlowLimitController

@GetMapping("/testD")public String testD() {/*try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}*/int age = 10/0;return "**********testD异常比例***********";}

image-20201106095040745

Sentinel降级-异常数

异常数:当资源近1分钟的异常数目超过阈值滞后进行熔断。由于统计时间窗口是分钟级别的,若时间窗口小于60s,则结束熔断状态后仍可能再进入熔断状态。

时间窗口一定要大于60秒

修改子项目(8401)的FlowLimitController

@GetMapping("/testE")public String testE() {int age = 10/0;return "********testE异常数********";}

运行报错。

设置异常数

image-20201106100140248

image-20201106100244080

Sentinel热点key

热点参数限流会统计参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流,热点参数限流可以看作是一种特殊的流量控制,仅包含热点参数的资源调用生效。

修改子项目(8401)的FlowLimitController

@GetMapping("/testHotKey")@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")public String testHotKey(@RequestParam(value = "p1",required = false) String p1,@RequestParam(value = "p2",required = false) String p2) {return "*****testHotKey successful**********";}public String deal_testHotKey(String p1, String p2, BlockException ex){return "********deal_testHotKey**********";}

运行image-20201106102634048

配置热点规则

image-20201106102717337

参数索引:对访问的第一个参数进行限流

当每秒访问多次的时候就会进行服务熔断。

image-20201106102829509

当把blockHandler参数去掉,一秒一次就会显示成功页面,当一秒访问多次的时候就会直接弹出错误页面(Error Page)。

参数例外项

普通:超过1秒钟一个之后,达到阈值1后马上被限流

我们希望p1参数当它是摸个特殊值时,它的限流值和平时不一样

假如当p1的值等于5时,它的阈值可以达到200

配置参数例外项

image-20201106104603378

image-20201106104706670

当p1的值不等于5时,阈值是1

当p1的值等于5时,阈值为200

image-20201106104822773

当代码中有错误它不会去报deal_testHotKey,而是会直接显示错误界面。

Sentinel系统规则

系统自适应限流

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

image-20201106121713542

Load自适应(仅对Linux/Unix-like机器生效):系统的load作为启发指标,进行自适应系统保护。当系统load超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR阶段)。系统容量有系统的maxQps*minRt估算得出,设定参考值一般是CPU cores * 2.5。

CPU usage(1.5.0+版本):当系统CPU使用率超过阈值即触发系统保护(取值范围0.0-1.0),比较灵敏。

平均RT:当单台机器所有入口流量的平均RT达到阈值即触发系统保护,单位是毫秒

并发线程数:当单台机器所有入口流量的并发线程数达到阈值即触发系统保护

入口QPS:当单台机器上所有入口流量的QPS达到阈值即触发系统保护

image-20201106122520361

SentinelResource配置

修改一个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 服务不可用");}

运行8401

image-20201106183123864

设置限流规则

image-20201106183205638

image-20201106183238199

按照Url地址限流

修改RateLimitController

//按照URl限流@GetMapping("/rateLimit/byUrl")@SentinelResource(value = "byUrl")public CommonResult byUrl() {return new CommonResult(200,"按Url限流测试OK",new Payment(2020L,"serial002"));}

image-20201106191827389

设置限流规则

image-20201106192031488

image-20201106192105862

上面兜底方案面临的问题

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

修改一个RateLimitController

//CustomerBlockHandler@GetMapping("/rateLimit/customerBlockHandler")@SentinelResource(value = "customerBlockHandler",blockHandlerClass = CustomerBlockHandler.class,blockHandler = "handlerException1")public CommonResult customerBlockHandler() {return new CommonResult(200,"按客户自定义",new Payment(2020L,"serial003"));}

新建一个CustomerBlockHandler.java

public class CustomerBlockHandler {public static CommonResult handlerException1(BlockException exception){return new CommonResult(444,"按客户自定义,global handlerException-------1");}public static CommonResult handlerException2(BlockException exception){return new CommonResult(444,"按客户自定义,global handlerException-------2");}
}

配置限流规则

image-20201106194631706

image-20201106194647996

image-20201106194701695

Sentinel服务熔断Ribbon环境

新建子项目(cloudalibaba-provider-payment9003)

pom.xml

<dependencies><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></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><!--引入自己定义的api通用包--><dependency><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></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><dependency><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version><scope>compile</scope></dependency></dependencies>

新建配置文件application.yml

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

新建主启动类

@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9003 {public static void main(String[] args) {SpringApplication.run(PaymentMain9003.class,args);}
}

新建业务类PaymentController

@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,"从入门到放弃"));hashMap.put(2L,new Payment(2L,"从删库到跑路"));hashMap.put(3L,new Payment(3L,"从进门到坐牢"));}@GetMapping("/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;}
}

新建子项目(cloudalibaba-provider-payment9003)

步骤按照上述

新建子项目(cloudalibaba-consumer-nacos-order84)

pom.xml

<dependencies><dependency><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></dependency><!--SpringCloud ailibaba nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></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><!--SpringCloud ailibaba sentinel --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</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>

新建application.yml配置文件

server:port: 84spring:application:name: nacos-order-consumercloud:nacos:discovery:server-addr: localhost:8848sentinel:transport:dashboard: localhost:8080port: 8719service-url:nacos-user-service: http://nacos-payment-provider

创建主启动类OrderNacosMain84

@SpringBootApplication
@EnableDiscoveryClient
public class OrderNacosMain84 {public static void main(String[] args) {SpringApplication.run(OrderNacosMain84.class,args);}
}

创建配置类ApplicationContextConfig

@Configuration
public class ApplicationContextConfig {@Bean@LoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}

创建业务类CircleBreakerController

@RestController
public class CircleBreakerController {public static final String SERVICE_URL = "http://nacos-payment-provider";@Resourceprivate 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("非法参数,异常");}else if(result.getData()==null) {throw new NullPointerException("该ID没有对应的记录,空指针异常");}return result;}
}

Sentinel服务熔断配置fallback

在子项目84上业务类CircleBreakerController加上兜底方法

@RestController
public class CircleBreakerController {public static final String SERVICE_URL = "http://nacos-payment-provider";@Resourceprivate RestTemplate restTemplate;@RequestMapping("/consumer/fallback/{id}")@SentinelResource(value = "fallback",fallback = "handerFallback")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("该ID没有对应的记录,空指针异常");}return result;}public CommonResult handlerFallback(@PathVariable Long id,Throwable e) {Payment payment = new Payment(id, null);return new CommonResult<>(444,"兜底异常,异常内容:"+e.getMessage(),payment);}
}

image-20201107110444452

fallback只负责业务异常。

Sentinel服务熔断配置blockhandler

修改子项目84上业务类CircleBreakerController

@RestController
public class CircleBreakerController {public static final String SERVICE_URL = "http://nacos-payment-provider";@Resourceprivate RestTemplate restTemplate;@RequestMapping("/consumer/fallback/{id}")//@SentinelResource(value = "fallback",fallback = "handerFallback") //fallback只处理业务出现异常@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("非法参数,异常");}else if(result.getData()==null) {throw new NullPointerException("该ID没有对应的记录,空指针异常");}return result;}/*public CommonResult handlerFallback(@PathVariable Long id,Throwable e) {Payment payment = new Payment(id, null);return new CommonResult<>(444,"兜底异常,异常内容:"+e.getMessage(),payment);}*/public CommonResult handlerFallback(@PathVariable Long id, BlockException blockException) {Payment payment = new Payment(id, null);return new CommonResult<>(445, "blockHandler-sentinel限流,无此流水:" + blockException.getMessage(), payment);}
}

添加降级规则

image-20201107141637276

image-20201107141736762

image-20201107141818351

blockHandler只负责sentinel控制台配置违规

Sentinel服务熔断配置fallback和blockhandler

若blockHandler和fallback都进行了配置,则被限流降级而抛出BlockException时只会进入blockHandler处理逻辑。

Sentinel服务熔断exceptionsTolgnore

修改子项目84上业务类CircleBreakerController

@RestController
public class CircleBreakerController {public static final String SERVICE_URL = "http://nacos-payment-provider";@Resourceprivate RestTemplate restTemplate;@RequestMapping("/consumer/fallback/{id}")//@SentinelResource(value = "fallback",fallback = "handerFallback") //fallback只处理业务出现异常//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规//@SentinelResource(value = "fallback",fallback = "handerFallback",blockHandler = "blockHandler")@SentinelResource(value = "fallback",fallback = "handerFallback",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("非法参数,异常");}else if(result.getData()==null) {throw new NullPointerException("该ID没有对应的记录,空指针异常");}return result;}public CommonResult handlerFallback(@PathVariable Long id,Throwable e) {Payment payment = new Payment(id, null);return new CommonResult<>(444,"兜底异常,异常内容:"+e.getMessage(),payment);}public CommonResult handlerFallback(@PathVariable Long id, BlockException blockException) {Payment payment = new Payment(id, null);return new CommonResult<>(445, "blockHandler-sentinel限流,无此流水:" + blockException.getMessage(), payment);}
}

运行

image-20201107143205986

假如4报异常,不再有fallback方法兜底,没有降级效果了。

Sentinel服务熔断OpenFeign

修改子项目(84)

pom.xml

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

修改application.yml

# 激活Sentinel对Feign的支持
feign:sentinel:enabled: true

在主启动类上面加上注解,开启Feign

@EnableFeignClients

创建service接口

@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)
public interface PaymentService {@GetMapping(value = "/paymentSQL/{id}")public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}

创建接口实现类PaymentFallbackService

@Component
public class PaymentFallbackService implements PaymentService {@Overridepublic CommonResult<Payment> paymentSQL(Long id) {return new CommonResult<>(444,"服务降级返回,----PaymentFallbackService",new Payment(id,"errorService"));}
}

在业务类CirleBreakerController添加

@Resourceprivate PaymentService paymentService;@GetMapping(value = "/paymentSQL/{id}")public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){return paymentService.paymentSQL(id);}

运行

当9003停止运行后,84会

image-20201107145607764

Sentinel持久化规则

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

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

修改子项目(8401)

application.yml

server:port: 8401spring:application:name: cloudalibaba-sentinel-servicecloud:nacos:discovery:server-addr: localhost:8848sentinel:transport:dashboard: localhost:8080       #配置Sentinel dashboard地址port: 8719      #默认8719端口,如果被占用会自动从8719开始依次+1,直到找到未被占用的端口#8719端口是应用和Sentinel控制台交互的端口datasource:ds1:nacos:server-addr: localhost:8848dataId: cloudalibaba-sentinel-servicegroupId: DEFAULT_GROUPdata-type: jsonrule-type: flow
management:endpoints:web:exposure:include: '*'

在nacos里面新建配置

image-20201107153103560

resource:资源名称;

limitApp:来源应用;

grade:阈值类型,0表示线程数、1表示QPS;

count:单机阈值;

strategy:流控模式,0表示直接,1表示关联,2表示链路;

controlBehavior:流控效果,0表示快速失败,1表示Warm up,2表示排队等待;

clusterMode:是否集群;

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

image-20201107153544722


http://www.ppmy.cn/news/765415.html

相关文章

mac升级或降级node版本

mac升级或降级node版本 前几天一个月薪35k的兄弟&#xff0c;给我推了一个人工智能学习网站&#xff0c;看了一段时间挺有意思的。包括语音识别、机器翻译等从基础到实战都有&#xff0c;很详细&#xff0c;分享给大家。大家及时保存&#xff0c;说不定啥时候就没了。 1、安装…

SQLServer2012数据库降级方法

我用SQL2012建的数据库结果在其他的电脑上都不能附加&#xff0c;版本太高不支持 打开SQL Server&#xff0c;连接到数据库&#xff0c;然后找到你要降级的数据库 右击数据库&#xff0c;有一个任务选项——扩展里面有一个生成脚本 生成脚本的窗口打开后&#xff0c;直接单…

如何把SQLServer数据库从高版本降级到低版本?

由于目前还广泛使用着SQLServer2000&#xff0c;很多公司又想使用新的SQLServer&#xff0c;从而直接【分离/附加】或者【备份/还原】数据库&#xff0c;在不同版本之间存放。往往就会遇到版本不兼容的问题。前几天遇到了从我本机2008R2上备份的一个数据库还原到2008上面时报错…

Mac版本降级教程

Mac版本降级教程 前情提要过程坎坷1、备份&#xff01;&#xff01;&#xff01;2、一些尝试&#xff08;坑&#xff0c;不要学&#xff09;2.1、直接在官网下载安装包2.2、回退到High Sierra2.2.1、需要抹除磁盘2.2.2、时间机器无法使用2.2.3、应该是可行的 3、真实的步骤3.1、…

ios虚拟服务器降级,iOS降级教程

SuccessionDown降级工具,目前支持的机型有6S、6SP、6、6P、5s。 SuccessionDown安装添加源:repo.matthewpison.github.io/ 支持6s系列从13.3.1降级到13.3.1~13.0之间的任意版本 支持6代系列从12.4.5降级到12.4.5~12.0之间的任意版本,甚至可以到11.3~11.4.1 支持5s从12.4.5…

SQL SERVER数据库降级方案

该文写于三年前&#xff0c;大家经历过SQL SERVER版本问题的&#xff0c;相信会对高版本数据库降成低版本有点印象。我当时是把一个2014版的数据库给降成低版本的&#xff0c;其实按照步骤一步步来&#xff0c;也能够顺利完成降级&#xff0c;只要把数据库的结构给搞好&#xf…

IOS14怎么降级回IOS13

IOS14怎么降级回IOS13&#xff1f;虽然新系统的各种新功能让人眼前一亮&#xff0c;但由于是beta 版本&#xff0c;难免存在某些影响体验的 BUG&#xff0c;例如占用过多存储容量、设备发烫、微信小程序闪退等。那么IOS14怎么降级回IOS13&#xff1f;下面就让小编给大家介绍一下…

iPhone系统可以降级吗?

iPhone发布新系统&#xff0c;大家总是会忍不住去更新&#xff0c;尝试新的功能&#xff0c;但是有些时候新的iOS可能并不适合我们的机型&#xff0c;这种时候&#xff0c;大家就会想到退回原来的系统。那么iPhone可以降级更新吗&#xff1f; 可以降级&#xff0c;但有条件 首…