温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Sentinel的使用分析

发布时间:2021-11-10 10:41:28 来源:亿速云 阅读:133 作者:柒染 栏目:大数据

本篇文章给大家分享的是有关Sentinel的使用分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

Sentinel能用来做什么?

  1. 限流

  2. 熔断降级

  3. 流量塑形

  4. 系统负载保护

  5. 热点防护 详细概念介绍请阅读:https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5

Sentinel基本概念

资源

资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。 只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

规则

围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

使用Sentinel

引入 Sentinel 依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.0</version>
</dependency>

定义资源和设置规则

以下代码将一段Java方法定义为保护资源,规则设置为每秒钟访问1次,通过控制台输出内容可以发现Sentinel生效。

public class demo {
    public static void main(String[] args) {
        // 配置规则.
        initFlowRules();

        while (true) {
            // 1.5.0 版本开始可以直接利用 try-with-resources 特性,自动 exit entry
            try (Entry entry = SphU.entry("sentinel-test1")) {
                // 被保护的业务逻辑
                System.out.println("业务资源访问成功!");
            } catch (BlockException ex) {
                // 处理被流控的逻辑
                System.out.println("资源访问失败!!!");
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("sentinel-test1");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS.
        rule.setCount(1);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
		}
}

定义资源的几种方法

抛出异常的方式定义资源

// 1.5.0 版本开始可以利用 try-with-resources 特性(使用有限制)
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
try (Entry entry = SphU.entry("resourceName")) {
  // 被保护的业务逻辑
  // do something here...
} catch (BlockException ex) {
  // 资源访问阻止,被限流或被降级
  // 在此处进行相应的处理操作
}

**注意: **

  1. 若 entry 的时候传入了热点参数,那么 exit 的时候也一定要带上对应的参数(exit(count, args)),否则可能会有统计错误。这个时候不能使用 try-with-resources 的方式。

  2. 通过 Tracer.trace(ex) 来统计异常信息时,由于 try-with-resources 语法中 catch 调用顺序的问题,会导致无法正确统计异常数,因此统计异常信息时也不能在 try-with-resources 的 catch 块中调用 Tracer.trace(ex)。

Entry entry = null;
// 务必保证 finally 会被执行
try {
  // 资源名可使用任意有业务语义的字符串,注意数目不能太多(超过 1K),超出几千请作为参数传入而不要直接作为资源名
  // EntryType 代表流量类型(inbound/outbound),其中系统规则只对 IN 类型的埋点生效
  entry = SphU.entry("自定义资源名");
  // 被保护的业务逻辑
  // do something...
} catch (BlockException ex) {
  // 资源访问阻止,被限流或被降级
  // 进行相应的处理操作
} catch (Exception ex) {
  // 若需要配置降级规则,需要通过这种方式记录业务异常
  Tracer.traceEntry(ex, entry);
} finally {
  // 务必保证 exit,务必保证每个 entry 与 exit 配对
  if (entry != null) {
    entry.exit();
  }
}

热点参数埋点示例:

Entry entry = null;
try {
    // 若需要配置例外项,则传入的参数只支持基本类型。
    // EntryType 代表流量类型,其中系统规则只对 IN 类型的埋点生效
    // count 大多数情况都填 1,代表统计为一次调用。
    entry = SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);
    // Your logic here.
} catch (BlockException ex) {
    // Handle request rejection.
} finally {
    // 注意:exit 的时候也一定要带上对应的参数,否则可能会有统计错误。
    if (entry != null) {
        entry.exit(1, paramA, paramB);
    }
}

返回布尔值方式定义资源

// 资源名可使用任意有业务语义的字符串
  if (SphO.entry("自定义资源名")) {
    // 务必保证finally会被执行
    try {
      /**
      * 被保护的业务逻辑
      */
    } finally {
      SphO.exit();
    }
  } else {
    // 资源访问阻止,被限流或被降级
    // 进行相应的处理操作
  }

**注意:**SphO.entry(xxx) 需要与 SphO.exit()方法成对出现,匹配调用,位置正确,否则会导致调用链记录异常,抛出ErrorEntryFreeException` 异常。

注解方式定义资源

// 原本的业务方法
// 配置 blockHandler 和 fallback 函数来进行限流之后的处理
@SentinelResource(value="资源名称", blockHandler = "blockHandlerForGetUser")
public User getUserById(String id) {
    throw new RuntimeException("getUserById command failed");
}

// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
public User blockHandlerForGetUser(String id, BlockException ex) {
    return new User("admin");
}

详细文档:https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

异步调用定义资源

try {
    AsyncEntry entry = SphU.asyncEntry(resourceName);

    // 异步调用.
    doAsync(userId, result -> {
        try {
            // 在此处处理异步调用的结果.
        } finally {
            // 在回调结束后 exit.
            entry.exit();
        }
    });
} catch (BlockException ex) {
    // Request blocked.
    // Handle the exception (e.g. retry or fallback).
}

规则的种类

流量控制规则 (FlowRule)

通过代码定义流量控制规则:

private void initFlowQpsRule() {
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule(resourceName);
    // set limit qps to 20
    rule.setCount(20);
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setLimitApp("default");
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

**注意:**同一个资源可以同时有多个限流规则,检查规则时会依次检查。 详细参考文档:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

熔断降级规则 (DegradeRule)

通过代码定义熔断降级规则:

private void initDegradeRule() {
    List<DegradeRule> rules = new ArrayList<>();
    DegradeRule rule = new DegradeRule();
    rule.setResource(KEY);
    // set threshold RT, 10 ms
    rule.setCount(10);
    rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
    rule.setTimeWindow(10);
    rules.add(rule);
    DegradeRuleManager.loadRules(rules);
}

**注意:**同一个资源可以同时有多个降级规则。 详细参考文档:https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

系统保护规则 (SystemRule)

通过代码定义系统保护规则:

private void initSystemRule() {
    List<SystemRule> rules = new ArrayList<>();
    SystemRule rule = new SystemRule();
    rule.setHighestSystemLoad(10);
    rules.add(rule);
    SystemRuleManager.loadRules(rules);
}

**注意:**系统规则只针对入口资源(EntryType=IN)生效。 详细参考文档:https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81

访问控制规则 (AuthorityRule)

很多时候,我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的访问控制(黑白名单)的功能。黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。 授权规则,即黑白名单规则(AuthorityRule)非常简单,主要有以下配置项:

  • resource:资源名,即规则的作用对象

  • limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB

  • strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式 通过代码定义访问控制规则:

private void initAuthorityRule() {
    AuthorityRule rule = new AuthorityRule();
		rule.setResource("test");
		rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
		rule.setLimitApp("appA,appB");
		AuthorityRuleManager.loadRules(Collections.singletonList(rule));
}

Sentinel Dashboard控制台的启动

从https://github.com/alibaba/Sentinel/releases下载jar包 使用如下命令启动:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

-Dserver.port参数指定控制台端口号 -Dcsp.sentinel.dashboard.server参数指定控制台服务地址 -Dproject.name参数指定项目名 访问指定服务地址,用户名、密码都是sentinel

Spring Boot项目连接控制台

添加依赖:

<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
			<version>0.9.0.RELEASE</version>
</dependency>

在application.yaml中进行简单的配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 // 控制台地址
  application:
    name: sentinel-demo // 在控制台中项目的名字

server:
  port: 9090

依赖自动识别HTTP协议的接口,在簇点链路中可以看到。在后面的操作按钮中可以进行各种规则限制。 Sentinel的使用分析

以上就是Sentinel的使用分析,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI