springcloud笔记(7)-限流降级Sentinel

官方文档:概述 | Spring Cloud Alibaba

basic-api-resource-rule | Sentinel (sentinelguard.io)

Sentinel是SpringCloudAlibaba的组件。

sentinel的功能

introduction | Sentinel

流量控制

熔断降级:降低调用链路中的不稳定资源

系统负载保护:让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求,放置系统雪崩。

限流降级

在微服务系统中,一个对外的业务功能可能会涉及很长的服务调用链路。当其中某个服务出现异常,如果没有服务调用保护 机制可能会造成该服务调用链路上大量相关服务直接或间接调用的服务器仍然持续不断发起请求,最终导致相关的所有服务资源耗尽产生异常发生雪崩效应。限流和降级分别作为在流量控制和服务保护方面的两个重要手段,可以有效地应对此类问题。

限流 blockHandler

限流是指对微服务系统中某个服务的某个接口的访问量进行限制,以避免过大的流量将服务实例击垮。其一般是通过为服务设置流量阈值,当达到限制的阈值时,可以采取一些策略进行处理,比如排队、返回错误信息等来对请求进行响应以实现对服务实例的保护。在微服务系统中,限流主要是针对服务提供者而言的。

降级 Fallback

降级是指当某个服务出现异常或者被限流时,对该服务的调用进行降级处理,比如返回一个默认值,返回一个兜底数据等。在微服务系统中,降级主要是针对服务消费者而言的。

Sentinel概述

Spring Cloud Alibaba 集成的开箱即用限流降级方案来自 Sentinel,其以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
  • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

官方示例:https://github.com/alibaba/spring-cloud-alibaba/tree/2022.x/spring-cloud-alibaba-examples/sentinel-example

对应项目的readme有教程

sentinel中的概念

资源:资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

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

sentinel的工作流程

basic-implementation | Sentinel

springboot中使用sentinel

quick-start | Sentinel

1、引入依赖

<dependency>

<groupId>com.alibaba.cloud</groupId>

<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>

</dependency>

IDEA里没有maven idea开发工具右侧没有maven工具栏 -- 源码巴士

打开的pom.xml文件中,鼠标右键,点击【 Add as Maven Project】解决

2. 接入限流埋点

埋点文档:annotation-support | Sentinel (sentinelguard.io)

-HTTP 埋点

Sentinel starter 默认为所有的 HTTP 服务提供了限流埋点,如果只想对 HTTP 服务进行限流,那么只需要引入依赖,无需修改代码。

- 自定义埋点

如果需要对某个特定的方法进行限流或降级,可以通过 `@SentinelResource` 注解来完成限流的埋点,示例代码如下:

```java

@SentinelResource("resource")

public String hello() {

return "Hello";

}

```

Sentinel 提供了 @SentinelResource 注解用于定义资源annotation-support | Sentinel

这里的hello()方法就成为了一个资源。

Sentinel 支持配置 blockHandlerfallback 函数来进行限流之后的处理。示例:

// 原本的业务方法.
@SentinelResource(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");
}

注意 blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。请注意 blockHandlerfallback 函数的形式要求,更多指引可以参见 Sentinel 注解支持文档

3. 配置限流规则

Sentinel 提供了两种配置限流规则的方式:代码配置 和 控制台配置。

代码配置

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

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控制台,

复制代码
https://edas-public.oss-cn-hangzhou.aliyuncs.com/install_package/demo/sentinel-dashboard.jar

启动

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

在应用的配置文件中,增加如下控制台配置信息:

spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080

这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。

更多 Sentinel 控制台的使用及问题参考 Sentinel控制台

访问控制台

启动sentinel-core-example

sentinel可以看到启动的应用

新增流控规则,资源名填写需要限流的 URL 相对路径或者是`@SentinelResource` 注解 `value` 字段的值,单机阈值选择需要限流的阈值,点击新增进行确认。(这里将值设置成了 1)

访问URL,当QPS超过1,可以看到限流效果。这里返回的是默认的效果,也可以自定义限流处理逻辑。

各种规则配置

basic-api-resource-rule | Sentinel (sentinelguard.io)

Sentinel 控制台

dashboard | Sentinel (sentinelguard.io)

实时监控

Sentinel 控制台支持实时监控查看,您可以通过 Sentinel 控制台查看各链路的请求的通过数和被限流数等信息。

其中 `p_qps` 为通过(pass) 流控的 QPS,`b_qps` 为被限流 (block) 的 QPS。

用jmeter对/hello进行压测,发现QPS超过100的会被拒绝,因为默认配置了系统规则入口QPS上限为100。

系统规则

客户端支持

Spring Cloud Alibaba 提供的 Sentinel 有关 Starter 提供了对 Spring Cloud 生态中如 OpenFeign、RestTemplate 等主流的客户端组件的适配支持。

OpenFeign

可以看官方示例sentinel-openfeign-example

sentinel,对程序内部异常(各种异常,包括超时)这种捕捉,显得很乏力,它主要是针对流量控制,系统吞吐量,或者是异常比例这种,会发生降级或熔断,但是当程序内部发生异常,直接返回给用户错误页面,根本不会触发异常比例这种降级。所以才需要整合open-feign 来解决程序内部异常时,配置相应的兜底方法


版权声明:本文为CSDN博主「hancoder」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/hancoder/article/details/109063671[​](https://sca.aliyun.com/zh-cn/docs/2022.0.0.0/user-guide/sentinel/advanced-guide#openfeign "​")

spring-cloud-starter-alibaba-sentinel 适配了 OpenFeign 组件。如果想使用,除了引入必要的 Starter 依赖外还需要在配置文件打开 sentinel 对 feign 的支持:

复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

feign.sentinel.enabled=true

这是一个 FeignClient 的简单使用示例:

java 复制代码
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
    @GetMapping(value = "/echo/{str}")
    String echo(@PathVariable("str") String str);
}

class FeignConfiguration {
    @Bean
    public EchoServiceFallback echoServiceFallback() {
        return new EchoServiceFallback();
    }
}

class EchoServiceFallback implements EchoService {
    @Override
    public String echo(@PathVariable("str") String str) {
        return "echo fallback";
    }
}

@FeignClient 注解中的所有属性,Sentinel 都做了兼容。

sentinel-openfeign-example

sentinel-openfeign-example定义了三个接口,三个接口调用httpbinClient的方法

在接口httpbinClient中,使用了@FeignClient注释,指定了访问的url和fallbackFactory = EchoServiceFallbackFactory.class,这个属性是用来指定当Feign客户端调用失败时使用的回退工厂类,类EchoServiceFallbackFactory返回了HttpbinClientFallback,

在HttpbinClientFallback中定义了每个方法的return,具体的失败规则在SentinelRulesConfiguration类中配置。

启动应用,1s内连续访问接口,可以看到降级规则生效,返回了fallback方法。

RestTemplate

spring-cloud-starter-alibaba-sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造 RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。

@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
    return new RestTemplate();
}

@SentinelRestTemplate 注解的属性支持限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)的处理。

其中 blockHandler 或 fallback 属性对应的方法必须是对应 blockHandlerClass 或 fallbackClass 属性中的静态方法。

该方法的参数跟返回值跟 org.springframework.http.client.ClientHttpRequestInterceptor#interceptor 方法一致,其中参数多出了一个 BlockException 参数用于获取 Sentinel 捕获的异常。

比如上述 @SentinelRestTemplate 注解中 ExceptionUtil 的 handleException 属性对应的方法声明如下:

public class ExceptionUtil {
    public static ClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException exception) {
        ...
    }
}

NOTE: 应用启动的时候会检查 @SentinelRestTemplate 注解对应的限流或降级方法是否存在,如不存在会抛出异常

@SentinelRestTemplate 注解的限流(blockHandler, blockHandlerClass)和降级(fallback, fallbackClass)属性不强制填写。

当使用 RestTemplate 调用被 Sentinel 熔断后,会返回 RestTemplate request block by sentinel 信息,或者也可以编写对应的方法自行处理返回信息。这里提供了 SentinelClientHttpResponse 用于构造返回信息。

Sentinel RestTemplate 限流的资源规则提供两种粒度:

  • httpmethod:schema://host:port/path:协议、主机、端口和路径

  • httpmethod:schema://host:port:协议、主机和端口

NOTE: 以 淘宝网 - 淘!我喜欢 这个 url 并使用 GET 方法为例。对应的资源名有两种粒度,分别是 GET:https://www.taobao.com 以及 GET:https://www.taobao.com/test。

相关推荐
Hello-Brand几秒前
Java核心知识体系10-线程管理
java·高并发·多线程·并发·多线程模型·线程管理
乐悠小码6 分钟前
数据结构------队列(Java语言描述)
java·开发语言·数据结构·链表·队列
史努比.8 分钟前
Pod控制器
java·开发语言
2的n次方_10 分钟前
二维费用背包问题
java·算法·动态规划
皮皮林55111 分钟前
警惕!List.of() vs Arrays.asList():这些隐藏差异可能让你的代码崩溃!
java
莳光.11 分钟前
122、java的LambdaQueryWapper的条件拼接实现数据sql中and (column1 =1 or column1 is null)
java·mybatis
程序猿麦小七16 分钟前
基于springboot的景区网页设计与实现
java·spring boot·后端·旅游·景区
weisian15122 分钟前
认证鉴权框架SpringSecurity-2--重点组件和过滤器链篇
java·安全
蓝田~24 分钟前
SpringBoot-自定义注解,拦截器
java·spring boot·后端
.生产的驴26 分钟前
SpringCloud Gateway网关路由配置 接口统一 登录验证 权限校验 路由属性
java·spring boot·后端·spring·spring cloud·gateway·rabbitmq