Redis+Lua脚本+AOP+反射+自定义注解,打造内部基础架构限流组件

发布于:2024-03-27 ⋅ 阅读:(47) ⋅ 点赞:(0)

1.开发自定义限流注解给全团队赋能共用,一个注解搞定

2.可配置【时间窗口内可以随意灵活调整时间和次数】 + 可拔插

3.支持高并发【redis下干的】且满足事务一致性要求,lua脚本

注意!限流是在Controller层做的,不要干到Service层【做业务逻辑的】

1.自定义注解RedisLimitAnnotation实现业务解耦

2.高并发实时配置下的LuaScript处理

3.自定义AOP切面类

RedisLimitController

@Slf4j
@RestController
public class RedisLimitController{
    @GetMapping("/redis/limit/test")
    public String redisLimit(){
        return "业务正常返回,订单流水:" + IdUtil.fastUUID();
    }
}

限流后

时间窗口在这等价于redis 的 key的过期时间

@Slf4j 
@RestController
// 1秒内只允许2个人点击
@RedisLimitAnnotation(key = "redis-limit:test" , permitsPerSecond = 2,expire = 1, msg = "当前排队人数过多,请稍后再试!")
public class RedisLimitController{
    @GetMapping("/redis/limit/test")
    public String redisLimit(){
        return "业务正常返回,订单流水:" + IdUtil.fastUUID();
    }
}

RedisConfig

redis序列化的工具配置类【一定要开启】

public class RedisConfig{
    // 执行  keys *
    // 野生:"\xac\xed\x00\aord:102"  序列化后:"ord:102"
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactor){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactor);
        // 设置key序列化方式String
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

RedisLimitAnnotation

@Retentiom(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Document
public @interface RedisLimitAnnotation{
    // 资源key唯一,不同接口不同流量控制 模拟Sentinel资源key resource
    String key() default "";
    // 最多访问限制次数
    long permitsPerSecond() default 2;
    // 过期时间 滑动窗空时间 单位秒 默认60秒
    long expire() default 60;
    // 得不到令牌提示语
    String msg() default "系统繁忙 点击太快请稍后重试";
}
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到