Sentinel降级简介

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

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

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的窗口,设置降级

当一秒钟打进来十个线程来调用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异常比例***********";}

Sentinel降级-异常数

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

时间窗口一定要大于60秒

修改子项目(8401)的FlowLimitController

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

运行报错。

设置异常数

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**********";}

运行

配置热点规则

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

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

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

参数例外项

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

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

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

配置参数例外项

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

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

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

Sentinel系统规则

系统自适应限流

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

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达到阈值即触发系统保护

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

设置限流规则

按照Url地址限流

修改RateLimitController

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

设置限流规则

上面兜底方案面临的问题

  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");}
}

配置限流规则

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);}
}

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);}
}

添加降级规则

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);}
}

运行

假如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会

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里面新建配置

resource:资源名称;

limitApp:来源应用;

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

count:单机阈值;

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

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

clusterMode:是否集群;

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

Sentinel降级服务相关推荐

  1. Sentinel降级简介_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0038

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 可以看看sentinel后台的降级 可以看到,当发生了熔断,也就是发生了错误以后,会熔断,熔断,就 ...

  2. Spring Cloud入门-Sentinel实现服务限流、熔断与降级(Hoxton版本)

    文章目录 Spring Cloud入门系列汇总 摘要 Sentinel简介 安装Sentinel控制台 创建sentinel-service模块 限流功能 创建RateLimitController类 ...

  3. Sentinel微服务流量控制熔断降级及稳定性监控IO框架

    目录 Sentinel 介绍 Sentinel 的历史 Sentinel 基本概念 资源 规则 Sentinel 功能和设计理念 流量控制 熔断降级 系统负载保护 Sentinel 是如何工作的 快速 ...

  4. SpringCloud微服务-服务注册发现-负载均衡-服务调用-服务降级-服务网关-配置中心-消息总线-消息驱动-链路追踪-alibaba-nacos-sentinel-seata理论原理分析

    SpringCloud理论技术 概述 ​ Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总 ...

  5. Hystrix 服务断路器(熔断器 )/服务降级/服务监控 hystrixDashboard

    1. 服务雪崩 多个微服务之间调用的时候, 假设微服务A 调用微服务B和微服务C, 微服务B和微服务C又调用其他的微服务, 这就是所谓的'扇出'. 如果扇出的链路上某个微服务的调用响应时间过长或者不可 ...

  6. 微服务之Hystrix(一):结合Eureka实现服务降级-服务熔断器处理

    目录 一:Hystrix简介 二:问题引入 三:线程隔离,服务降级原理 四:使用Hystrix 五:熔断器的引入 六:测试熔断器 代码地址:代码地址-GitHub 一:Hystrix简介 在微服务场景 ...

  7. sentinel限流_微服务架构进阶:Sentinel实现服务限流、熔断与降级

    摘要 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案,Sentinel 作为其核心组件之一,具有熔断与限流等一系列服务保护功能,本文将对其用法进行详细介绍. Senti ...

  8. Sentinel微服务限流、熔断、降级介绍(一)

    概述 在互联网应用中,会有很多突发性的高并发访问场景,比如双11大促.秒杀等.这些场景最大的特点就是访问量会远远超出系统所能够处理的并发数. 在没有任何保护机制的情况下,如果所有的流量都进入服务器,很 ...

  9. 手把手带你领略双十一背后的核心技术Sentinel之服务的熔断降级

    这种日子该到头了{这种日子该到头了}这种日子该到头了 代码来自:https://blog.csdn.net/Kevinnsm/article/details/117520719?spm=1001.20 ...

最新文章

  1. Oracle 中利用一个表结构拷贝成另外的表
  2. Openstack组件部署 — Networking service_Compute Node
  3. libtool的工作原理
  4. 提升命令行效率的Bash快捷键
  5. python 对象序列化 pickling_[Python]对dat文件的操作:序列化对象
  6. delphi tclientsocket接收不到返回数据_RS—485中教你主站发送报文结构、从站返回报文结构?系列11...
  7. SpringBoot项目实现配置实时刷新功能
  8. 虚拟机安装菜鸟教程(2)——CentOS8系统安装 网络 时间配置
  9. php 置多条cookie,php 在cookie存储多个的简单示例
  10. mvn 错误: @param 未找到
  11. 华为服务器 修改为传统模式,电脑设置成服务器模式
  12. 上班要了解的一些法律条例
  13. 流利阅读 2019.2.27 How sky-high rents forced people into imaginative alternatives
  14. 加州大学戴维斯分校 计算机科学,2020年加州大学戴维斯分校排名TFE Times美国最佳计算机科学硕士专业排名第43...
  15. Android 产生ANR后的Trace文件的解析
  16. python的time模块使用
  17. Opcodes 说明
  18. php怎么判断是否手机网站,php,js判断网站是不是手机访问
  19. 研大考研不是骗子:考研政治时事之破除国企岗位
  20. Win7右下角网络图标异常解决方法

热门文章

  1. maya 杀毒软件官方下载地址及教程
  2. 9.ffplayer 原理、架构及代码分析——变速播放的实现
  3. WAS以及weblogic日志说明
  4. windows通过安卓手机的【usb共享网络】上网突然无法上网的解决
  5. gradle下载安装(个人记录)
  6. Haiwell Cloud Scada Designer 3
  7. 说说为什么阿里要破冰?
  8. Keil(MDK)STM32和51版本详细安装
  9. STM32F4单片机bootloader及在线升级IAP基本原理
  10. SQL必知必会(一)SQL基础篇