常见限流算法介绍 和 Spring Cloud Sentinel使用方式

sentinel 限流及熔断

为什么要限流呢?对于一些突发流量,如双11大促,甚至恶意攻击,这时系统的访问量远远超出系统的承受能力,如果不做任何保护措施, 服务器资源会耗尽,进而系统不可用。

限流就是限制系统访问量,以牺牲部分用户的可用性为代价,保证系统可用性。

常见的限流算法

计数器算法

计数器算法 实现简单存在临界问题,窗口切换时 会出现临界问题,可以用如短信发生频次限制等场景。

滑动窗口

滑动窗口算法是对计数器算法改进,将固定窗口中分割多个小时间窗口,统计每个小时间窗口记录总数,滑动窗口更加平滑,很好的解决了临界问题。

令牌桶算法

有个固定容量的令牌桶 用来存储令牌,系统以固定的速率 向令牌桶中添加令牌,超出容量的令牌会被丢弃。

用户请求时,先需要从令牌桶中获取令牌, 如果令牌桶中没有令牌则拒绝该请求,否则消耗一个令牌,请求被接收。

限流原理:当请求速度大于令牌生成的速度时, 桶内令牌不断被消耗,直到耗尽,从而触发限流。

适用于需要处理突发流量的场景,允许在短时间突发流量的处理

漏桶算法

有个固定容量的漏桶,存放用户请求的。

用户请求需要经过漏桶,桶满了,则拒绝请求, 漏桶里请求以固定速率流出,流出的请求被处理,漏桶算法处理速度是恒定的,

适用于需要平滑流量的场景,可以有效防止突发流量导致的网络拥塞,当流量高于处理速度时,部分请求会有一定的延迟。

Sentinel 应用

Sentinel是一款轻量级流量控制组件,可以轻松实现流量整形熔断保护机制,有效提升系统的健壮性和可用性。

Sentinel提供了灵活的规则配置方式,

  • 控制台配置

  • 扩展点配置

Sentinel Dashboard

下载指定的版本sentinel-dashboard.jar, 执行下面命令启动,启动成功后,http://{ip}:8080/ 进入控制台,默认用户名/密码:sentinel/sentinel,即可进入管理控制台

bash 复制代码
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.8.jar

代码配置规则方式

Sentinel 支持SPI方式配置规则。

  • 实现 InitFunc接口

  • resources/META-INF/services 下添加文件

com.alibaba.csp.sentinel.init.InitFunc 内容实现类全路径

bash 复制代码
com.codetonight.rule.CustomerRuleInitFunc
java 复制代码
public class CustomerRuleInitFunc implements InitFunc {
    @Override
    public void init() throws Exception {
        List<FlowRule> rules = new ArrayList<>();

        FlowRule rule = new FlowRule();
        rule.setCount(5);
        rule.setResource("customer");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        rules.add(rule);

        FlowRuleManager.loadRules(rules);
    }
}

配置文件

配置Sentinel Dashboard ip和端口

bash 复制代码
spring.cloud.sentinel.transport.dashboard=yourIp:8080

限流使用方式

  • SphU.entry(资源名称)

    触发限流规则会抛出 BlockException,捕获该异常进行熔断处理、服务降级等逻辑

  • SphO.entry(资源名称)

触发限流规则 该方法会返回 false,需要与SphO.exit();搭配使用

  • @SentinelResource(value = "资源名称",blockHandler = "blockHandler")

触发限流会调用blockHandler, blockHandler指定的方法,在原来参数列表上多了BlockException, 可以在blockHandler实现熔断逻辑、服务降级。

示例代码

java 复制代码
    @GetMapping("/testBlock")
    public String testBlock(){
        try(Entry entry = SphU.entry("hello")){
            return "OK";
        }catch (BlockException e){
            return "BlockException";
        }
    }
    
    @GetMapping("/testBlock2")
    public String testBlock2(){
        if(SphO.entry("hello")){
            SphO.exit();
            return "OK";
        }else {
            return "BlockException";
        }
    }
    
    
    @GetMapping("/say")
    @SentinelResource(value = "hello",blockHandler = "blockHandlerHello")
    public String say(){
        return "Hello world";
    }


    public String blockHandlerHello(BlockException e){
        if(e != null){
            e.printStackTrace();
        }
        return "限流了";
    }
    
复制代码
    <!-- Spring Cloud Alibaba Sentinel -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

总结

通过sentinel组件很容易对相关接口进行限流,只需要配置相应的规则即可,sentinel提供了Sentinel Dashboard,在控制台调整规则的参数,无需重启应用即可生效。使用方式支持注解方式 @SentinelResource,可以做到对业务代码无入侵。

相关推荐
小江的记录本8 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:G1:Region分区、Mixed GC、回收流程、适用场景(高频)(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·spring cloud·面试
苏渡苇13 小时前
强强联合:OpenFeign 整合 Sentinel
spring boot·spring cloud·微服务·sentinel·openfeign
一个儒雅随和的男子15 小时前
Spring cloud组件gateway网关详细剖析
spring·spring cloud·gateway
Mr. zhihao17 小时前
Redis 脑裂深度解析:Sentinel 与 Cluster 机制、流程及对比
数据库·redis·sentinel
woniu_buhui_fei17 小时前
Sentinel实现限流
微服务·sentinel
weixin_4074438717 小时前
基于Sentinel-1/2数据特征优选的冬小麦识别
人工智能·算法·随机森林·机器学习·sentinel
苏渡苇18 小时前
微服务间的远程接口调用:OpenFeign 的使用
spring cloud·微服务·架构·springboot·openfeign·sca
凌云若寒18 小时前
SENTINEL软件
学习·sentinel·产品经理·制造·软件需求
未若君雅裁18 小时前
Ribbon 负载均衡策略与自定义规则
spring cloud·ribbon·负载均衡
梵得儿SHI19 小时前
SpringCloud 进阶拓展:性能优化指南(缓存三大问题 + 分库分表入门)
spring cloud·缓存·微服务·性能优化·高并发·分库分表·数据库优化