Sentinel 框架详解

这篇具有很好参考价值的文章主要介绍了Sentinel 框架详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、简介

Sentinel 是一个高可用、高扩展、高稳定性的开源流量控制和熔断降级框架,可以在分布式系统中实现实时的流量控制,防止系统因流量过大导致系统崩溃和服务降级。

Sentinel 提供了以下功能:

  • 流量控制:通过配置不同的规则,对请求流量进行限制。
  • 熔断降级:当系统异常情况发生时,可以自动熔断系统,保证系统的可用性。
  • 系统负载保护:在系统负载高峰期间,可以限制请求流量,避免系统资源耗尽。
  • 实时监控:可以实时监控系统的请求流量、响应时间、错误率等指标。

Sentinel 面向所有的 Java 应用,可以支持基于 Spring Cloud、Dubbo、gRPC 等服务框架的应用,也可以集成到基于 Tomcat、Jetty 等 Web 容器的应用中。

二、Sentinel 的原理

Sentinel 实现流量控制和熔断降级的原理是通过对应用程序进行拦截,然后根据预定义的规则,来判断该请求是否被允许或者需要进行降级处理。

Sentinel 的拦截器会在应用程序中建立一个责任链,对请求进行逐一拦截。在拦截过程中,Sentinel 会对 Request、Response、Exception 等参数进行统计,根据统计信息来对请求进行熔断或者限流等操作。

衡量系统稳定性主要有以下三个指标:

  • TPS(Transactions Per Second):每秒钟处理的事务数。
  • RT(Response Time):响应时间,即从发送请求到接收到响应的时间。
  • Error Rate:错误率,即发生错误的请求次数占总请求数的比例。

Sentinel 根据这三个指标来评估应用程序的健康状况,当这些指标达到某个阈值时,Sentinel 会自动触发相应的流量控制和熔断降级操作。

三、Sentinel 快速入门

以下是 Sentinel 快速入门的几个步骤:

  1. 首先,在 Maven 中引入 Sentinel 的依赖:

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        <version>2.2.1.RELEASE</version>
    </dependency>
    
  2. 在 Spring Boot 中配置 Sentinel 的启动参数:

    spring.cloud.sentinel.transport.dashboard=http://localhost:8080
    spring.cloud.sentinel.transport.port=8719
    # Sentinel 控制台连接超时时间(ms)
    spring.cloud.sentinel.transport.dashboard.request-timeout=5000
    # 配置资源的默认规则
    spring.cloud.sentinel.rules.defaults[0].grade=QPS
    spring.cloud.sentinel.rules.defaults[0].count=10
    

    其中,spring.cloud.sentinel.transport.dashboard 配置了 Sentinel 控制台的地址,spring.cloud.sentinel.transport.port 配置了 Sentinel 的启动端口。

  3. 在需要进行流量控制的方法上添加注解:

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
    public String demoMethod() {
      return "Hello World";
    }
    
    public String handleBlock(BlockException ex) {
      return "请求被拦截: " + ex.getClass().getSimpleName();
    }
    

    在上述代码中,我们使用 @SentinelResource 注解对 demoMethod 方法进行了流量控制,并设置了 fallback 方法为 handleBlock。当触发限流时,就会执行 handleBlock 方法来返回自定义的响应结果。

四、使用 Sentinel 进行熔断降级

Sentinel 不仅能够进行流量控制,还能够进行熔断降级。当系统出现一定程度的异常时,就会触发熔断降级策略来保证系统的可用性。以下是使用 Sentinel 进行熔断降级的几个步骤:

  1. 在业务方法上添加 @SentinelResource 注解,并指定 fallbackClassfallback 属性值:

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock", fallbackClass = DemoServiceFallback.class, fallback = "fallback")
    public String demoMethod() {
      return "Hello World";
    }
    
    public String handleBlock(BlockException ex) {
      return "请求被拦截: " + ex.getClass().getSimpleName();
    }
    

    在上述代码中,我们指定了 fallbackClassfallback 属性来定义 fallback 方法的实现类和方法名。当服务出现熔断降级时,就会执行 fallback 方法来返回自定义的响应结果。

  2. 定义 fallback 方法及其实现类:

    public class DemoServiceFallback {
      public static String fallback() {
        return "请求被熔断降级";
      }
    }
    

    在上述代码中,我们定义了 fallback 方法及其实现类 DemoServiceFallback。当服务出现熔断降级时,就会执行 fallback 方法来返回自定义的响应结果。

五、Sentinel 的流控规则和热点参数限流

Sentinel 支持多种多样的流控规则和热点参数限流策略,可以根据业务场景进行灵活配置。

流控规则

Sentinel 的流控规则有以下几种:

  1. QPS 流量控制:通过对 API 进行 QPS 控制,即限定接口在一定时间内能够处理的请求次数。

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
    @RateLimiter(10)
    public String demoMethod() {
      return "Hello World";
    }
    
    public String handleBlock(BlockException ex) {
      return "请求被拦截: " + ex.getClass().getSimpleName();
    }
    

    在上述代码中,我们使用 @RateLimiter 注解对接口进行了 QPS 流控,并设置了限流阈值为 10。

  2. 线程数流控:通过对线程池中的线程数进行限制,来避免线程池过载。

    @SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
    @ThreadPool(name = "demoMethod", coreSize = 5, maxQueueSize = 10)
    public String demoMethod() {
      return "Hello World";
    }
    
    public String handleBlock(BlockException ex) {
      return "请求被拦截: " + ex.getClass().getSimpleName();
    }
    

    在上述代码中,我们使用 @ThreadPool 注解对线程池进行了流控,并设置了线程池的核心线程数为 5。

热点参数限流

热点参数限流是 Sentinel 的一个重要特性,可以有效避免因某个参数的恶意使用而导致整个系统崩溃的情况。例如,假设有一个商品详情接口,其中的参数 skuId 很可能存在热点,即某些具体的商品 skuId 会被大量请求。如果不进行限流,当出现某个特定 skuId 的恶意攻击时,系统可能会崩溃。

以下是一个使用 Sentinel 实现热点参数限流的示例:

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
@HotParam(value = "skuId", mode = ParamFlowItem.FlowControlMode.QPS, threshold = 100)
public String demoMethod(@RequestParam Long skuId) {
  return "Hello World";
}

在上述代码中,我们使用 @HotParam 注解对 skuId 参数进行限流,并设置了限流阈值为 100 QPS。这样,当某个 skuId 的请求超过 100 QPS 时,就会触发 Sentinel 的限流机制。通过这种方式,我们可以避免因某个热点参数的异常使用而导致整个系统崩溃的情况。

六、Sentinel 的优缺点

Sentinel 作为一个成熟的分布式系统的流量防卫兵,具有以下优点:

  • 功能丰富:Sentinel 提供了流量控制、熔断降级、系统保护、实时监控等全方位的服务质量保障。
  • 易于使用:Sentinel 提供了友好的 Web 界面,可以方便的进行规则的配置和管理。
  • 高度可定制:Sentinel 提供了多种 SPI 扩展点,可以根据业务需求进行自定义扩展。
  • 开源免费:Sentinel 是完全开源的,可以免费使用。

当然,Sentinel 还存在以下一些缺点:

  • 不支持语言多样性:Sentinel 目前只支持 Java 应用,对于其他编程语言的应用不够友好。
  • 文档略显简单:Sentinel 的文档虽然已经比较全面,但是在一些实践场景中仍然存在一些坑点需要注意。

七、Sentinel 高级特性

同时支持同步和异步调用

Sentinel 可以方便地支持同步和异步调用。 对于同步调用,可以使用 @SentinelResource 注解,在注解中指定需要进行保护的方法,并设置相应的熔断降级、流控规则等限制条件。

对于异步调用,则需要使用 Sentinel 提供的异步 Entry 类实现保护。 在使用异步 Entry 进行保护时,需要在异步调用过程中插入 Sentinel 的拦截器,并在异步操作完成后手动释放相应的资源,以便 Sentinel 统计并记录相应的数据。

例如,以下是一个使用异步 Entry 进行保护的示例:

CompletableFuture.supplyAsync(() -> {
  Entry entry = null;
  try {
    entry = SphU.asyncEntry("demoMethod");
    // 异步逻辑
    return "Hello World";
  } catch (BlockException ex) {
    return "blocked by Sentinel: " + ex.getClass().getSimpleName();
  } finally {
    if (entry != null) {
      entry.exit();
    }
  }
}).thenAccept(result -> System.out.println("result: " + result));

在上述代码中,我们首先使用 SphU.asyncEntry 方法创建一个异步 Entry,然后在异步逻辑中执行业务操作。要注意的是,当异步操作完成时,需要手动调用 entry.exit() 方法释放相应的资源。

支持多种限流模式

Sentinel 支持多种限流模式,可以根据实际需求选择不同的限流算法。

  • 直接模式:直接对资源进行限制,超出阈值即触发限流。
  • 关联模式:通过关联资源来进行限流,例如对某个 API 进行流量控制时,可以通过关联访问该 API 的数据库连接池来实现流量控制。
  • 链路模式:通过对整个链路进行流量控制来保障系统的稳定性。

使用关联模式和链路模式时,需要在规则中设置相关的关联链接和链路信息。

例如,以下是一个使用关联模式进行流量控制的示例:

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
public void demoMethod(@RequestParam("id") Long id) {
  System.out.println("request id: " + id);
}

@Bean
public RequestOriginParser requestOriginParser() {
  return new DemoRequestOriginParser();
}

public static class DemoRequestOriginParser implements RequestOriginParser {
  @Override
  public String parseOrigin(HttpServletRequest request) {
    String origin = request.getParameter("origin");
    if (StringUtils.isEmpty(origin)) {
      return "unknown";
    }
    return origin;
  }
}

@Configuration
public class SentinelConfig {

  @Autowired
  private RequestOriginParser requestOriginParser;

  @PostConstruct
  public void init() {
    FlowRuleManager.register2(Arrays.asList(
        new FlowRule("demoMethod").setCount(5)
            .setGrade(RuleConstant.FLOW_GRADE_QPS)
            .setLimitApp("default")
            .as(FlowRule.class)
            .setStrategy(RuleConstant.STRATEGY_RELATE)
            .setRefResource("demoDatabase")));
  }

  @Bean
  public SentinelResourceAspect sentinelResourceAspect() {
    return new SentinelResourceAspect();
  }

  @Bean
  public SentinelServletRequestAspect sentinelServletRequestAspect() {
    return new SentinelServletRequestAspect();
  }
}

在上述代码中,我们使用 @SentinelResource 注解进行流量控制,并通过 setRefResource 和 setStrategy 来关联数据库连接池资源,并设置限流策略为关联模式。

支持多种规则匹配方式

Sentinel 支持多种规则匹配方式,可以根据实际需求选择不同的规则匹配策略。

  • 精确匹配:精确匹配是最常用的匹配方式,可以根据资源名称、限流参数等精确匹配规则。
  • 子串匹配:通常用于对资源名称进行模糊匹配,例如对某个 API 的所有请求进行限流。
  • 正则匹配:可以根据正则表达式进行规则匹配,提供更高级别的灵活性。

例如,以下是一个使用正则匹配规则的示例:

@SentinelResource(value = "demoMethod", blockHandler = "handleBlock")
public void demoMethod(@RequestBody Map<String, Object> data) {
  System.out.println("request data: " + data);
}

@Configuration
public class SentinelConfig {

  @PostConstruct
  public void init() {
    SystemRuleManager.loadRules(Collections.singletonList(
        new SystemRule()
            .setHighestSystemLoad(1.0)
            .setAvgLoad(0.8)
            .setQps(200))));
    ParamFlowRuleManager.loadRules(Collections.singletonList(
        new ParamFlowRule()
            .setParamIdx(0)
            .setGrade(RuleConstant.FLOW_GRADE_QPS)
            .setCount(5)
            .setDurationInSec(1)
            .setParamFlowItemList(Collections.singletonList(
                new ParamFlowItem().setObject("special_object")
                    .setCount(2)))));
    DegradeRuleManager.loadRules(Collections.singletonList(
        new DegradeRule("demoMethod")
            .setCount(100)
            .setTimeWindow(10)
            .setGrade(RuleConstant.DEGRADE_GRADE_RT)
            .setCount(20)
            .setMinRequestAmount(10))));
    FlowRuleManager.loadRules(Collections.singletonList(
        new FlowRule()
            .setGrade(RuleConstant.FLOW_GRADE_QPS)
            .setResourceRegex("/api/.*")
            .setCount(10)
            .setLimitApp("default")
            .as(FlowRule.class))));
  }

  @Bean
  public SentinelResourceAspect sentinelResourceAspect() {
    return new SentinelResourceAspect();
  }
}

在上述代码中,我们使用 setResourceRegex 方法设置了一个正则匹配规则,对所有以 /api/ 开头的资源进行流量控制。

八、使用案例

使用 Sentinel 和 Spring Cloud Gateway 实现网关限流

首先,我们需要在项目中引入 Sentinel 和 Spring Cloud Gateway 的依赖:

<!-- 引入 Sentinel -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- 引入 Spring Cloud Gateway -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

然后,我们可以在 application.yml 文件中添加 Sentinel 和 Spring Cloud Gateway 的相关配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8250

server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
        - id: test_route
          uri: http://httpbin.org
          predicates:
            - Path=/anything/**

在上面的配置中,我们指定了 Sentinel 的 dashboard 地址和 Spring Cloud Gateway 的端口号,在 Spring Cloud Gateway 中添加了一个名为 test_route 的路由,匹配路径为 /anything/**,并将该路由转发到 http://httpbin.org

接下来,我们需要为 Spring Cloud Gateway 添加 Sentinel 规则,以控制请求的流量:

@Bean
public SentinelGatewayFilterFactory sentinelGatewayFilterFactory() {
    return new SentinelGatewayFilterFactory();
}

@Bean
public GatewayFilterChain gatewayFilterChain(RouteLocator routeLocator,
                                             List<GatewayFilterFactory> gatewayFilters) {
    DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(routeLocator.getRoutes(), gatewayFilters);
    chain.add(0, sentinelGatewayFilterFactory.apply(new Object()));
    return chain;
}

在上面的代码片段中,我们创建了一个名为 sentinelGatewayFilterFactory 的 Bean,用于创建 Sentinel 的网关过滤器,并添加到 Gateway 中。

最后,我们需要在 Sentinel dashboard 中进行规则配置,以控制请求流量:

  • 打开 Sentinel 控制台,在左侧导航栏中,选择 Flow,并点击 新增
  • Resource 输入框中输入 /anything/**
  • 限流阈值 输入框中输入限制请求流量的最大数值。
  • 点击 新增

使用 Sentinel 和 RocketMQ 实现消息流量控制

首先,我们需要在项目中引入 Sentinel 和 RocketMQ 的依赖:

<!-- 引入 Sentinel -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- 引入 RocketMQ -->
<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.0.3</version>
</dependency>

然后,在 application.yml 文件中添加 Sentinel 和 RocketMQ 的相关配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8250

rocketmq:
  name-server: localhost:9876
  producer:
    group: my-group

其中,我们指定了 Sentinel 的 dashboard 地址和 RocketMQ 的 NameServer 地址,以及 RocketMQ 的生产者组名。

接下来,我们需要为生产者添加 Sentinel 规则,以控制消息发送的流量:

@Slf4j
@Service
public class MyProducer {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @PostConstruct
    public void init() {
        // 添加 Sentinel 规则
        String resourceName = "myTopic:myTag";
        String ruleKey = "myRuleKey";
        int threshold = 100;
        DegradeRule rule = new DegradeRule(resourceName, ruleKey, threshold);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        rule.setTimeWindow(10);
        List<DegradeRule> rules = new ArrayList<>();
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

    public void sendMessage(String message) {
        try {
            rocketMQTemplate.convertAndSend("myTopic", "myTag", message);
        } catch (Exception e) {
            log.error("发送消息失败,message: {}", message, e);
        }
    }
}

在上面的代码中,我们为 myTopic:myTag 资源添加了一条 Sentinel 规则,该规则的作用是:当该资源的 RT(响应时间)超过 10 毫秒时,将触发熔断,拒绝进一步的请求,防止影响消息系统的正常运行。规则的阈值为 100,即当一秒钟内超过 100 条消息时会触发限流。

最后,在消费者中也需要添加 Sentinel 的规则,以控制消息消费的流量:

@Slf4j
@Service
public class MyConsumer {

    @RocketMQMessageListener(topic = "myTopic", consumerGroup = "my-group")
    @SentinelResource(value = "myTopic:myTag", blockHandler = "handleBlockedMessage")
    public void handleMessage(@Payload String message) {
        log.info("接收到消息:{}", message);
    }

    public void handleBlockedMessage(String message, BlockException e) {
        log.error("消息被拒绝,message: {}", message);
    }
}

在上面的代码中,我们为 myTopic:myTag 资源添加了 Sentinel 规则,并指定了发生 Sentinel 规则限制时的处理方法。在消费过程中,如果超过 Sentinel 规则的阈值,则会触发限流,拒绝进一步的消息消费。文章来源地址https://www.toymoban.com/news/detail-474115.html

到了这里,关于Sentinel 框架详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Redis】高可用之二:哨兵(sentinel)

     本文是Redis系列第5篇,前4篇欢迎移步  【Redis】不卡壳的 Redis 学习之路:从十大数据类型开始入手_AQin1012的博客-CSDN博客 关于Redis的数据类型,各个文章总有些小不同,我们这里讨论的是Redis 7.0,为确保准确,我们直接看官网。 https://blog.csdn.net/aqin1012/article/details/130365083 【

    2024年02月12日
    浏览(56)
  • Redis-Sentinel高可用架构学习

    Redis-Sentinel高可用架构 Redis主从复制过程: 主从同步原理 Redis Sentinel(哨兵)高可用集群方案: Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案 。 当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redi

    2024年02月08日
    浏览(33)
  • 使用 Docker Compose 部署 Redis Sentinel 高可用架构

    在现代应用中,无法容忍系统中断或数据丢失。Redis 作为一种高性能的内存数据库,被广泛应用于缓存、会话管理等场景。然而,即使我们拥有可伸缩的 Redis Cluster 集群,也需要考虑在主节点故障时自动切换到从节点的机制。这时候 Redis Sentinel 就派上用场了。高可用性是分布

    2024年02月13日
    浏览(42)
  • 【Spring教程21】Spring框架实战:Spring事务简介、AOP事务管理、代码示例全面详解

    欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》,本文的上一篇为《AOP(面对切面编程)知识总结》 事务作用:在数据层保障一系列的数据库

    2024年02月04日
    浏览(44)
  • 简介:在这篇教程中,我们将使用React.js框架创建一个简单的聊天机器人的前端界面,并利用Dialogflo

    作者:禅与计算机程序设计艺术 介绍及动机 聊天机器人(Chatbot)一直是互联网领域中的热门话题。而很多聊天机器人的功能都依赖于人工智能(AI)技术。越来越多的企业希望拥有自己的聊天机器人系统,从而提升自己的竞争力。为此,业界也出现了很多基于开源技术或云

    2024年02月06日
    浏览(57)
  • Spring Cloud 之 Sentinel简介与GATEWAY整合实现

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。 熔断 微服务架构的系统通常会包含

    2024年02月19日
    浏览(41)
  • Sentinel如何实现对分布式系统的高可用性和流量控制?我们通过源码一起学习

    前言:大家好,我是小威,24届毕业生,在一家满意的公司实习。本篇文章将详细介绍Sentinel源码实现对分布式系统高可用性和流量控制,后续文章将详细介绍Sentinel的其他知识。 如果文章有什么需要改进的地方还请大佬不吝赐教 👏👏。 小威在此先感谢各位大佬啦~~🤞🤞

    2024年02月06日
    浏览(42)
  • 服务容错框架Sentinel入门

    Sentinel,阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。分布式系统的流量防卫兵。 特征: 丰富的应用场景:秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、

    2024年02月08日
    浏览(102)
  • Sentinel 流量控制框架

    1. Sentinel 是什么? Sentinel是由阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件。 2. 主要优势和特性 轻量级,核心库无多余依赖,性能损耗小。 方便接入,开源生态广泛。 丰富的流量控制场景。 易用的控制台,提供实时监控、机器发现、规则管理

    2024年02月09日
    浏览(82)
  • ARM可用的可信固件项目简介

    安全之安全(security²)博客目录导读 目录 一、TrustedFirmware-A (TF-A) 二、MCUboot 三、TrustedFirmware-M (TF-M) 四、TF-RMM 五、OP-TEE

    2024年02月08日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包