常见限流算法介绍 和 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,可以做到对业务代码无入侵。

相关推荐
杨荧17 小时前
【开源免费】基于Vue和SpringBoot的水果购物网站(附论文)
前端·javascript·jvm·vue.js·spring boot·spring cloud·开源
杨荧17 小时前
【开源免费】基于Vue和SpringBoot的服装生产管理系统(附论文)
前端·javascript·jvm·vue.js·spring boot·spring cloud·开源
.生产的驴20 小时前
SpringBoot 监听Redis键过期事件 过期监听
java·spring boot·redis·后端·spring·spring cloud·微服务
codefly-xtl21 小时前
sentinel使用手册
sentinel
跳跳的向阳花1 天前
03-13、SpringCloud Alibaba第十三章,升级篇,服务降级、熔断和限流Sentinel
spring·spring cloud·sentinel
customer082 天前
【开源免费】基于SpringBoot+Vue.JS教学资源库系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
tjiawen2 天前
医院管理系统
java·spring boot·spring·spring cloud·tomcat·maven
java使徒2 天前
kafka数据在服务端时怎么写入的
java·jvm·spring·spring cloud·kafka·mybatis·nio