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

相关推荐
喂完待续43 分钟前
【序列晋升】28 云原生时代的消息驱动架构 Spring Cloud Stream的未来可能性
spring cloud·微服务·云原生·重构·架构·big data·序列晋升
惜.己14 小时前
Docker启动失败 Failed to start Docker Application Container Engine.
spring cloud·docker·eureka
你是人间五月天16 小时前
sentinel实现控制台与nacos数据双向绑定
windows·sentinel
无名客016 小时前
sentinel限流常见的几种算法以及优缺点
算法·sentinel·限流
chenrui31020 小时前
Spring Boot 和 Spring Cloud: 区别与联系
spring boot·后端·spring cloud
tsxchen21 小时前
centos9安装sentinel
sentinel
寒士obj1 天前
Sentinel服务治理:服务降级、熔断与线程隔离
sentinel
iiYcyk1 天前
Hystrix与Sentinel-熔断限流
hystrix·sentinel·springcloud
勇往直前plus1 天前
Sentinel微服务保护
java·spring boot·微服务·sentinel
喂完待续2 天前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升