使用Sentinel滑动窗口实现限流和降级

 更新时间:2023年09月04日 08:25:06   作者:小威要向诸佬学习呀  
Sentinel 是一个开源的高可用性、高扩展性的实时流量控制框架,它可以用于保护服务稳定性,防止系统因为流量过大而崩溃,这篇文章我们所介绍的是滑动窗口,它是 Sentinel 实现限流和降级的重要组件之一,感兴趣的同学跟着小编来看看吧

Sentinel滑动窗口前言

Sentinel 是一个开源的高可用性、高扩展性的实时流量控制框架,它可以用于保护服务稳定性,防止系统因为流量过大而崩溃。今天我们所介绍的,是滑动窗口,它是 Sentinel 实现限流和降级的重要组件之一。

Sentinel滑动窗口原理

滑动窗口通常由一个固定大小的时间窗口和一个可滑动的数据结构组成,例如队列或滑动块。在 Sentinel 中,滑动窗口被分为计数器类型和预算类型

计数器滑动窗口:计数器滑动窗口维护一个周期内请求的总数,当周期结束后,滑动窗口会被清空,开始下一个周期的计数。在 Sentinel 中,计数器滑动窗口通过 AtomicLong 数组实现,数组的长度代表时间窗口的大小,每个元素代表该时间片保存的请求次数。

预算滑动窗口:预算滑动窗口维护周期内预算资源的使用情况,以便根据实际资源需要进行限流或降级。预算类型的滑动窗口可以设置阈值,并支持动态调整。在 Sentinel 中,预算滑动窗口通常用于 CPU 使用率、线程池等容量资源的控制

除此之外,Sentinel 还提供了基于单机、集群和分布式三种模式的滑动窗口实现。其中,单机模式下将使用本地内存来维护滑动窗口数据结构;集群模式下,各节点会通过多播或 Redis 等方式共享相同的计数器数据;分布式模式下,则允许多个服务节点公用同一组滑动窗口数据。

在使用 Sentinel 进行限流和降级时,用户可以通过配置规则来指定需要监控的目标资源,并设置相应的阈值和处理策略。例如,在限流场景下,用户可以设置最大 QPS,并指定超过该阈值的请求将会被丢弃或返回特定的错误码。在降级场景下,用户可以设置响应时间、异常比例等阈值,并指定相应的降级策略,例如返回默认值或者直接抛出异常。

如何在项目中使用滑动窗口

以实际的项目为例子,我们有一个服务用于提供用户信息查询接口,每秒钟最多只能处理 10 次查询请求,并且如果连续 5 秒内的请求次数超过 50 次,则触发限流或降级操作

在 Sentinel 中,我们首先需要定义一个 FlowRule 数组用于配置针对该服务的限流规则,在这块项目例子中,它们是每秒钟限流到 10 个请求和 5 秒内超过 50 次请求两种限制:

FlowRule rule1 = new FlowRule();
rule1.setResource("queryUser");
rule1.setCount(10);
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
FlowRule rule2 = new FlowRule();
rule2.setResource("queryUser");
rule2.setCount(50);
rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule2.setStrategy(RuleConstant.STRATEGY_CHAIN);
rule2.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);

我们先对以上代码进行解释,“queryUser” 代表资源名称,这个可以自己定义,然后设置了resource、count、grade以及对于第二个规则还增加了三个属性stratety, controlBehavior和controlBehavior。其中 count 表示限流阈值,即每秒钟最多可以处理多少个请求;grade 表示限流模式,QPS(每秒钟最多允许通过的请求数量);strategy 表示限流策略;controlBehavior 表示流量控制的行为。

接下来,我们需要通过执行如下代码初始化 Sentinel:

List<FlowRule> rules = new ArrayList<>();
rules.add(rule1);
rules.add(rule2);
FlowRuleManager.loadRules(rules);

我们这里定义了一个 FlowRule 数组,将前面定义好的两个规则加入到列表中,然后通过 FlowRuleManager.loadRules() 方法加载这些规则。

现在,我们可以在查询用户信息的方法上增加 @SentinelResource 注解,并在该注解中设置 blockHandler 和 fallback 属性来处理限流和降级异常:

@SentinelResource(value = "queryUser", blockHandler = "queryUserBlockHandler",
    fallback = "queryUserFallback")
public UserInfo queryUser(String userId) {
    // 查找用户信息的实现
}
// 限流/降级处理函数
public UserInfo queryUserBlockHandler(String userId, BlockException ex) {
    // 返回具体的错误信息
}
// 降级处理
public UserInfo queryUserFallback(String userId, Throwable ex) {
    // 返回降级后的响应
}

以上代码中我们定义了一个名为“queryUser”的资源,它被 @SentinelResource 注解所修饰,blockHandler 属性表示当该服务触发限流或降级时调用的函数,fallback 属性表示服务出现异常时的回退函数。

最后,我们可以通过对定时任务进行调度,模拟10秒内对同一个 API 请求用户数据的场景,例如代码如下:

public class QueryUserTask implements Runnable {
    private static final Random random = new Random();
    @Override
    public void run() {
        // 模拟 10 秒内对同一个 API 请求用户数据
        for (int i = 0; i < 20; i++) {
            String userId = "user-" + (i % 5);
            queryUser(userId);
            try {
                Thread.sleep(random.nextInt(500));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

我们可以在 QueryUserTask 内部实现每隔一秒获取一次用户信息,检测系统是否触发限流或降级保护。如果触发了规则中配置的限流规则,那么 Sentinel 将执行相应的措施进行处理。

好了,本篇文章就先分享到这里了,后续将会继续介绍sentinel详细的其他方面的知识。

到此这篇关于使用Sentinel滑动窗口实现限流和降级的文章就介绍到这了,更多相关Sentinel限流和降级内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Sentinel熔断规则原理示例详解分析

    Sentinel熔断规则原理示例详解分析

    这篇文章主要介绍了Sentinel熔断规则,采用了示例代码的方式对Sentinel熔断规则进行了详细的分析,以便广大读者朋友们更易理解,有需要的朋友可以参考下
    2021-09-09
  • Mybatis中一对多(collection)和一对一(association)的组合查询使用

    Mybatis中一对多(collection)和一对一(association)的组合查询使用

    这篇文章主要介绍了Mybatis中一对多(collection)和一对一(association)的组合查询使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • MyBatis XML去除多余AND|OR前缀或逗号等后缀的操作

    MyBatis XML去除多余AND|OR前缀或逗号等后缀的操作

    这篇文章主要介绍了MyBatis XML去除多余AND|OR前缀或逗号等后缀的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 23种设计模式(9) java桥接模式

    23种设计模式(9) java桥接模式

    这篇文章主要为大家详细介绍了java设计模式之桥接模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Java非静态成员变量之死循环(详解)

    Java非静态成员变量之死循环(详解)

    下面小编就为大家带来一篇Java非静态成员变量之死循环(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • RabbitMQ死信机制实现延迟队列的实战

    RabbitMQ死信机制实现延迟队列的实战

    本文主要介绍了RabbitMQ死信机制实现延迟队列的实战,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • SpringBoot熔断机制之CircuitBreaker详解

    SpringBoot熔断机制之CircuitBreaker详解

    这篇文章主要介绍了SpringBoot熔断机制之CircuitBreaker详解,SpringBoot的熔断机制在微服务架构中扮演着重要角色,其中CircuitBreaker是其核心机制之一,用于防止服务的异常状态影响到整个系统的运作,需要的朋友可以参考下
    2023-10-10
  • 浅谈spring和spring MVC的区别与关系

    浅谈spring和spring MVC的区别与关系

    下面小编就为大家带来一篇浅谈spring和spring MVC的区别与关系。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • Java如何做带复选框的菜单实例代码

    Java如何做带复选框的菜单实例代码

    大家好,本篇文章主要讲的是Java如何做带复选框的菜单实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • 基于springMvc+hibernate的web application的构建

    基于springMvc+hibernate的web application的构建

    下面小编就为大家带来一篇基于springMvc+hibernate的web application的构建。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10

最新评论