SpringCloudAlibaba Sentinel

SpringCloudAlibaba Sentinel

Sentinel 流量控制、熔断降级

Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel主要功能:熔断、限流(细粒度的)、监控。信号量限流

Sentinel分为两个部分:
1、核心库(Java客户端)不依赖任何框架/库,能够运行于所有Java运行时环境,同时对Dubbo/Spring Cloud等框架也有较好的支持。
2、控制台(DashBoard)基于SpringBoot开发,打包后可以直接运行。

问题
方法限流的次数是根据什么决定的?答:根据业务逻辑的复杂度:1.IO瓶颈、2.计算的瓶颈。

@SentinelResource 注解

Sentinel 提供了 @SentinelResource 注解用于定义资源,标识资源是否被限流、降级,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException等。

注解中的配置项解读:

  1. value:资源名称,必需项(不能为空)
  2. entryType:entry 类型,可选项(默认为 EntryType.OUT)
  3. blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  4. fallback / fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore
    里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
    4.1 返回值类型必须与原函数返回值类型一致;
    4.2 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
    4.3 fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  5. defaultFallback(since 1.6.0)
    默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback函数签名要求:exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入fallback 逻辑中,而是会原样抛出。
    5.1 返回值类型必须与原函数返回值类型一致;
    5.2 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
    5.2 defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。   特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException直接抛出(若方法本身未定义 throws BlockException 则会被 JVM 包装一层UndeclaredThrowableException)。
      从 1.4.0版本开始,注解方式定义资源支持自动统计业务异常,无需手动调用 Tracer.trace(ex) 来记录业务异常。Sentinel 1.4.0以前的版本需要自行调用 Tracer.trace(ex) 来记录业务异常。
  6. 注意点:
    6.1 注解方式埋点不支持 private 方法。
    6.2 1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理。
    6.3 一般推荐将 @SentinelResource 注解加到服务实现上,而在 Web 层直接使用 Spring Cloud Alibaba 自带的 Web 埋点适配。
sentinel 客户端启动命令
java -Dserver.port=8086 -Dcsp.sentinel.dashboard.server=localhost:8086 -jar sentinel-dashboard-1.8.1.jar

创建子项目

新建业务模块business

pom.xml

引入 spring-cloud-starter-alibaba-sentinel 和 spring-cloud-openfeign-core

    <parent>
        <artifactId>alm-cloudartifactId>
        <groupId>com.alm.cloudgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <groupId>com.alm.cloud.businessgroupId>
    <artifactId>alm-businessartifactId>
    <version>1.0-SNAPSHOTversion>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
            <version>2021.1version>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-openfeign-coreartifactId>
            <version>3.0.1version>
        dependency>
    dependencies>
project>
application.yml
server:
  port: 9011

spring:
  application:
    name: alm-business
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
        client-ip: 192.168.1.3 #当前项目地址,如果sentinel服务器地址和项目地址一致可不填写
      eager: true
feign:
  sentinel:
    enabled: true
UserController.java

SentinelResource 注解,标识资源是否被限流、降级。

@RestController
public class UserController {
    @Resource UserService userService;

    @SentinelResource(value = "/business/getUser", blockHandler="fallback")
    @GetMapping(value="/business/getUser")
    public Object getUser(Integer userId){
        //一、真正的业务逻辑,被保护的资源
        if(userId == null){
            System.out.println("【熔断降级】 远程服务查询异常 null");
            throw new RuntimeException("【熔断降级】 远程服务数据查询异常,或用户信息不存在!");
        }
        User user = userService.getUser(userId);
        System.out.println("Business getUser, uid:" + userId);
        return Rsp.end(user);
    }

    @ResponseBody
    public Object fallback(Integer userId, BlockException e){ //BlockException 作为参数必须加上
        System.out.println("【服务降级】 fallback...");
        return Rsp.end(Result.Err.ERR_SYSTEM_EXCEPTION, "【服务降级】 fallback...");
    }
}
UserService.java、UserServiceImpl.java
public interface UserService {
    public User getUser(Integer userId);
}

@Service
public class UserServiceImpl implements UserService{
    public User getUser(Integer userId){
        //一、真正的业务逻辑,被保护的资源
        return new User(20636, "张三", "150xxx");
    }
}

MySentinelConfig.java

错误提示的统一配置

在Sentinel进行流量管理控制中,需要统一处理返回异常信息,在1.8版本官方改成了BlockExceptionHandler这个接口与实现。

@Configuration
public class MySentinelConfig implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception{
        // BlockException 异常接口,其子类为Sentinel五种规则异常的实现类
        // AuthorityException 授权异常
        // DegradeException 降级异常
        // FlowException 限流异常
        // ParamFlowException 参数限流异常
        // SystemBlockException 系统负载异常
        String msg = "";
        if (e instanceof FlowException) {
            msg = "限流了";
        }else if (e instanceof DegradeException) {
            msg = "降级了";
        }else if (e instanceof ParamFlowException) {
            msg = "热点参数限流";
        }else if (e instanceof SystemBlockException) {
            msg = "系统规则(负载/...不满足要求)";
        }else if (e instanceof AuthorityException) {
            msg = "授权规则不通过";
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        String error = JSON.toJSONString(Rsp.end(Result.Err.ERR_FAIL, msg));//响应结构体
        response.getWriter().write(error);
    }
}

Sentinel Dashboard

下载并启动应用程序 sentinel-dashboard-1.8.1.jar

添加流控规则
SpringCloudAlibaba Sentinel_第1张图片
统一配置
限流了:请求多次之后,拦截到FlowException
降级了:出现一次异常,拦截到DegradeException
SpringCloudAlibaba Sentinel_第2张图片
SpringCloudAlibaba Sentinel_第3张图片

添加降级策略:异常数

SpringCloudAlibaba Sentinel_第4张图片
拦截到接口的自定义fallback 错误,通过自定义 throw new RuntimeException使得系统拦截到
SpringCloudAlibaba Sentinel_第5张图片

参考地址

使用 Sentinel 实现降级
https://www.jianshu.com/p/fc903afc81c4

sentinel1.8自定义错误信息
https://blog.csdn.net/lovoo/article/details/119082146

Sentinel限流、降级的统一处理
https://zhuanlan.zhihu.com/p/150058613

制定热点限流规则
https://blog.csdn.net/gloamer/article/details/118858762

你可能感兴趣的:(SpringCloud,spring,cloud)