Sentinel入门与进阶:微服务流量控制的最佳实践 ( 五 )

7. 熔断降级

Sentinel除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。

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

Sentinel 和 Hystrix 的原则是一致的: 当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。

由于网络或者自身的原因,我们的服务并不能保证100%可用,如果某个服务出现问题,调用这个服务就会出现阻塞的现象,此时,如果有大量请求涌入,线程资源就会消耗殆尽,导致微服务整体瘫痪,这时我们就要考虑服务不可用时的处理方式,也就是熔断和降级。我们先说降级。我们关闭nacos-server服务来制造这种场景。

限流降级指标有三个,如下图:

  1. 慢调用比例

  2. 异常比例

  3. 异常数

7.1. 慢调用比例

慢调用比例 (DEGRADE_GRADE_RT):当资源的平均响应时间超过阈值DegradeRule 中的 count,以 ms 为单位,默认上限是4900ms)之后,资源进入准降级状态。如果1s之内持续进入 5 个请求 ,它们的 RT 都持续超过这个阈值,那么在接下来的时间窗口DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回(抛出 DegradeException)。在下一个时间窗口到来时, 会接着再放入5个请求, 再重复上面的判断。

7.1.1.配置中心:超时时间100ms,熔断时间10s

json 复制代码
[
    {
        "resource":"/sentinelTest/sayHello",
        "grade": 0,
        "count": 100,
        "timeWindow": 10,
        "minRequestAmount": 5 
    }
]

7.1.2.项目中增加 配置

properties 复制代码
spring.cloud.sentinel.datasource.ds-degrade.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds-degrade.nacos.data-id=${spring.application.name}-sentinel-degrade
spring.cloud.sentinel.datasource.ds-degrade.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds-degrade.nacos.rule-type=degrade
spring.cloud.sentinel.datasource.ds-degrade.nacos.data-type=json

7.1.3.查看Sentinel Dashboard 降级

7.1.4.测试

代码每次执行要休眠1s, 也就是说请求肯定都会超时。

java 复制代码
    @RequestMapping("/sayHello")
    public String sayHello(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("count:" + count++ + ", date:" + new Date());
        return "hello";
    }

先执行postmain,配置如下:每 10 ms 发一个请求

10s之内,都是熔断界面

7.2. 异常比例

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

7.2.1.修改配置中心

json 复制代码
[
    {
        "resource":"/sentinelTest/sayHello",
        "grade": 0,
        "count": 100,
        "timeWindow": 10,
        "minRequestAmount": 5 
    },
     {
        "resource":"testMethod",
        "grade": 1,
        "count": 0.5,
        "timeWindow": 3,
        "minRequestAmount": 2 
    }
]

7.2.2.查看Sentinel Dashboard

7.2.3.修改testMethod()方法

java 复制代码
    @Override
    @SentinelResource(value = "testMethod", blockHandler = "blockMethod")
    public String testMethod() {
        // 随机 0或1 , 如果是 0 就会出现异常
        System.out.println(5 / (int) (Math.random() * 2));
        return "这是service中的方法";
    }

7.2.4.测试

7.3. 异常数

异常数 (DEGRADE_GRADE_EXCEPTION_COUNT):当资源近 1 分钟的异常数目超过阈值之后会进行熔断。

7.4.熔段

无论是触发了限流规则或者降级规则,都会执行blockHandler。

如果想将限流及异常做个区分的话,我们可以利用熔断来处理服务出现异常的情况。

fallback 对应熔断 处理方法

java 复制代码
package com.yuan.scasentineldashboard.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.yuan.scasentineldashboard.service.TestService;
import org.springframework.stereotype.Service;

@Service
public class TestServiceImpl implements TestService {

    @Override
    @SentinelResource(value = "testMethod", blockHandler = "blockMethod", fallback = "fallMethod")
    public String testMethod() {
        System.out.println(5 / (int) (Math.random() * 2));
        return "这是service中的方法";
    }

    public String blockMethod(BlockException e){
        return "方法被限流了";
    }

    public String fallMethod(){
        return "方法被熔断了";
    }
}
相关推荐
知识即是力量ol3 分钟前
初识 Kafka(一):分布式流平台的定义、核心优势与架构全景
java·分布式·kafka·消息队列
爱吃生蚝的于勒7 分钟前
【Linux】线程概念(一)
java·linux·运维·服务器·开发语言·数据结构·vim
kong79069289 分钟前
Nginx性能优化
java·nginx·性能优化
Pluchon10 分钟前
硅基计划4.0 算法 简单模拟实现位图&布隆过滤器
java·大数据·开发语言·数据结构·算法·哈希算法
我命由我1234510 分钟前
Java 泛型 - Java 泛型通配符(上界通配符、下界通配符、无界通配符、PECS 原则)
java·开发语言·后端·java-ee·intellij-idea·idea·intellij idea
Seven9710 分钟前
AQS深度探索:以ReentrantLock看Java并发编程的高效实现
java
4311媒体网19 分钟前
C语言操作符全解析 C语言操作符详解
java·c语言·jvm
淡忘_cx19 分钟前
使用Jenkins自动化部署spring-java项目+宝塔重启项目命令(2.528.2版本)
java·自动化·jenkins
毕设源码-钟学长24 分钟前
【开题答辩全过程】以 基于SSM的孤儿救助信息管理系统设计与实现为例,包含答辩的问题和答案
java
独自破碎E24 分钟前
【曼哈顿距离】BISHI25 最大 FST 距离
java·开发语言