4

【深入浅出Sentinel原理及实战】「基础实战专题」零基础实现服务流量控制实战开发指南...

 1 year ago
source link: https://www.cnblogs.com/liboware/p/17019943.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

你若要喜爱你自己的价值,你就得给世界创造价值

Sentinel的组成部分

Sentinel 主要由以下两个部分组成。

  • Sentinel核心库(Java客户端) :Sentinel的核心库不依赖任何框架或库,能够运行于Java 8及以上的版本的运行时环境中,同时对 Spring Cloud、Dubbo 等微服务框架提供了很好的支持。

  • Sentinel控制台(Dashboard) :Sentinel提供的一个轻量级的开源控制台,它为用户提供了机器自发现、簇点链路自发现、监控、规则配置等功能。

Sentinel 核心库不依赖 Sentinel Dashboard,但两者结合使用可以有效的提高效率,让 Sentinel 发挥它最大的作用。

Sentinel的工作机制

  • 对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。
  • 根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便您定义及改变规则。
  • Sentinel 提供实时的监控系统,方便您快速了解目前系统的状态

Sentinel 的开发流程

Sentinel 的开发流程如下:

  • 引入Sentinel依赖:在项目中引入 Sentinel 的依赖,将 Sentinel 整合到项目中;

  • 定义资源:通过对主流框架提供适配或 Sentinel 提供的显式 API 和注解,可以定义需要保护的资源,此外 Sentinel 还提供了资源的实时统计和调用链路分析;

  • 定义规则:根据实时统计信息,对资源定义规则,例如流控规则、熔断规则、热点规则、系统规则以及授权规则等。

  • 检验规则是否在生效:运行程序,检验规则是否生效,查看效果。

引入Sentinel的Maven依赖

如果您的应用使用了 Maven,则在 pom.xml 文件中加入以下代码即可:

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

如果您未使用依赖管理工具,请到 Maven Center Repository 直接下载 JAR 包。

up-ec8ae042fbf3fb1c92e3795c8bd105aa819.png

Sentinel的基本概念

Sentinel的基本概念有两个部分,它们分别是:资源和规则。

「资源」 是Sentinel的关键概念。它可以是Java应用程序中的任何内容,例如由应用程序提供的服务或者是服务里的方法,甚至可以是一段代码。

资源的定义

通过Sentinel提供的API来定义一个资源,使其能够被Sentinel保护起来,通常情况下,我们可以使用方法名、URL 甚至是服务名来作为资源名来描述某个资源。

只要通过 Sentinel API 定义的代码,就是资源,能够被Sentinel保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

采用原生API的模式

最常用的资源是我们代码中的Java方法,也可以更灵活的定义你的资源。例如,把需要控制流量的代码用Sentinel API的SphU.entry("resourceName")entry.exit() 包围起来即可。参考代码如下:

java
public static void main(String[] args) {
    // 配置规则.
    initFlowRules();
    while (true) {
        // 1.5.0版本开始可以直接利用 try-with-resources 特性
        try (Entry entry = SphU.entry("resourceName")) {
            // 被保护的逻辑
            System.out.println("resource");
     } catch (BlockException ex) {
            // 处理被流控的逻辑
	    System.out.println("blocked!");
	 }
    }
}

在上面的例子中,将System.out.println("resource"); 作为资源(被保护的逻辑),用 API 包装起来。完成以上两步后,代码端的改造就完成了。

采用AOP注解的模式

通过提供的@SentinelResource注解支持模块,来定义我们的资源,@SentinelResource注解是Sentinel提供的最重要的注解之一,它还包含了多个属性,如下表。

属性 说明 必填与否 使用要求
value 用于指定资源的名称 必填 ——
entryType entry 类型 可选项(默认为 EntryType.OUT) ——
blockHandler 服务限流后会抛出 BlockException 异常,而 blockHandler 则是用来指定一个函数来处理 BlockException 异常的。简单点说,该属性用于指定服务限流后的后续处理逻辑。 可选项 blockHandler 函数访问范围需要是 public;返回类型需要与原方法相匹配;参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException;blockHandler 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 blockHandler 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
blockHandlerClass 若 blockHandler 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。 可选项 不能单独使用,必须与 blockHandler 属性配合使用;该属性指定的类中的 blockHandler 函数必须为 static 函数,否则无法解析。
fallback 用于在抛出异常(包括 BlockException)时,提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。 可选项 返回值类型必须与原函数返回值类型一致;方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;fallback 函数默认需要和原方法在同一个类中,若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
fallbackClass 若fallback函数与原方法不在同一个类中,则需要使用该属性指定 fallback 函数所在的类。 可选项 不能单独使用,必须与 fallback 或 defaultFallback 属性配合使用;该属性指定的类中的 fallback 函数必须为 static 函数,否则无法解析。
defaultFallback 默认的 fallback 函数名称,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。 可选项 返回值类型必须与原函数返回值类型一致;方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常;defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
exceptionsToIgnore 用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。 可选项 ——

注意:在 Sentinel 1.6.0 之前,fallback 函数只针对降级异常(DegradeException)进行处理,不能处理业务异常。

使用注解模式的定义资源的代码:

java
@SentinelResource("resourceName")
public void helloWorld() {
    // 资源中的逻辑
    System.out.println("resource");
}

注意:注解支持模块需要配合 Spring AOP 或者 AspectJ 一起使用。

「规则」 是围绕资源而设定的,Sentinel支持 流量控制、熔断降级、系统保护、来源访问控制和热点参数 等多种规则,所有这些规则都可以动态实时调整。

通过流控规则来指定允许该资源通过的请求次数,例如下面的代码定义了资源,每秒最多只能通过 20 个请求。

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

完成上面步骤之后,Sentinel 就能够正常工作了。

当服务运行之后,我们可以在日志 ~/logs/csp/${appName}-metrics.log.xxx 里看到下面的输出:

highlighter- code-theme-dark
|--timestamp-|------date time----|--resource-|p |block|s |e|rt
1529999204000|2022-06-26 15:41:44| resource |20|0    |20|0|0
1529999205000|2022-06-26 15:41:45| resource |20|5579 |20|0|728
1529999206000|2022-06-26 15:41:46| resource |20|15698|20|0|0
1529991207000|2022-06-26 15:41:47| resource |20|19262|20|0|0
1529993308000|2022-06-26 15:41:48| resource |20|19502|20|0|0
1529991209000|2022-06-26 15:41:49| resource  |20|18386|20|0|0
  • p 代表通过的请求
  • block 代表被阻止的请求
  • s 代表成功执行完成的请求个数
  • e 代表用户自定义的异常
  • rt 代表平均响应时长。

可以看到,这个程序每秒稳定输出 "resource" 20 次,和规则中预先设定的阈值是一样的。

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK