分布式开发之系统限流-滑动窗口、漏桶算法和令牌桶算法详解以及各自优缺点

本文介绍了分布式系统限流的三种算法:滑动窗口、漏桶和令牌桶算法,详细分析了各自的实现逻辑、优缺点。滑动窗口适合少量流量突发场景,但效率较低;漏桶算法适用于银行金融项目,不支持流量突发;令牌桶算法允许流量突发,常用于电商、直播业务,具有高效查找和修改操作。
摘要由CSDN通过智能技术生成

准备工作

1.了解lua语言的基本类型、语法、简单函数等(学习一下

2.搭建redis集群环境redis-cli 3.2.11

3.自定义注解以及切面配置拦截器

1.项目配置

<!-- spring切面 -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.6</version>
</dependency>

<!-- jedisCluster -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.1.1</version>
</dependency>

2.限流注解配置

限流注解支持配置时间段(限流需要统计的时间片段)、水流速率(漏桶算法中的水流速、令牌桶算法中的生成令牌速率)、最大访问数(限流阀值)、限流方式(目前支持自定义key和IP,部分代码没贴出来,我把git地址贴在文章最后,有需要可以看一下)、自定义key(需要限流的key,支持spel表达式)、限流算法(本篇文章主要讲市面上主流的几种算法:滑动窗口、漏桶算法、令牌桶算法)

package com.dubbo.core.flowcontrol;

import com.dubbo.core.flowcontrol.enums.AlgorithmEnum;
import com.dubbo.core.flowcontrol.enums.FlowControlEnum;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 限流
 * @author lizixiang
 * @since 2022/4/8
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface FlowControl {

    /**
     * 时间段(s)
     */
    long duration() default 60;

    /**
     * 水流速率(/s)
     */
    int flowRate() default 1;

    /**
     * 最大访问数
     */
    int max() default 1000;

    /**
     * 限流方式
     */
    FlowControlEnum[] method() default FlowControlEnum.IP;

    /**
     * 自定义key
     */
    String key() default "" ;

    /**
     * 限流算法
     */
    AlgorithmEnum algorithm() default AlgorithmEnum.SLIDE_WINDOW;

}

3.配置切面

注解的参数不是所有都用到,后面会仔细讲解,切面主要就是对注解参数的解析再封装,我这里只写了自定义key,获取IP的方式各个公司都不一样,这里就不贴出来了。最后一句代码用到了自定义工厂类和策略模式的组合,不同的算法写到了指定的策略类当中,看不懂的同学自行百度学习一下。

strategy.flowControl(dto);
package com.dubbo.core.flowcontrol;

import com.dubbo.core.flowcontrol.enums.AlgorithmEnum;
import com.dubbo.core.flowcontrol.enums.FlowControlEnum;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author lizixiang
 * @since 2022/4/8
 */
@Aspect
@Component
public class FlowControlAspect {

    private static final Logger logger = LoggerFactory.getLogger(FlowControlAspect.class);

    @Pointcut("@annotation(com.dubbo.core.flowcontrol.FlowControl)")
    public void flowControl() {
    }

    @Before(value = "flowControl()")
    public void before(JoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        FlowControl flowControl = method.getAnnotation(FlowControl.class);
        String key = flowControl.key();
        AlgorithmEnum algorithm = flowControl.algorithm();
        FlowControlEnum[] enums = flowControl.method();
        long duration &#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值