Java基于Guava包实现接口限流

本文介绍了如何在Spring框架中使用注解和AOP实现接口限流,通过`ServerLimit`注解配置限流参数,`ServerLimitAspect`切面负责处理限流逻辑,示例了简单的限流方案,并提到进阶应用时可考虑使用Redis作为存储机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 定义注解声明

/**
 * 接口限流注解
 *
 * @author panzx
 **/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface ServerLimit {

    /**
     * 接口控制标识,不同的key不同的流量控制
     */
    String key() default "";

    /**
     * 每秒最大流量
     */
    int limitPerSecond() default 10;
}

2. 定义切面

/**
 * 限流切面
 *
 * @author panzx
 **/
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class ServerLimitAspect {

    private final HttpServletRequest request;

    /**
     * key:归档同一组限流方案 => 用户名 + @ServerLimit.key
     */
    private final Map<String, RateLimiter> limiterMap = Maps.newConcurrentMap();

    @Around("@annotation(com.dlm.openapi.annotation.ServerLimit)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        ServerLimit serverLimit = method.getAnnotation(ServerLimit.class);
        if (serverLimit == null) {
            return joinPoint.proceed();
        }
        // 根据实际情况选择是否需要这个
        String userName = "";
        // 限流key由租户编码 + 接口名称组成
        String limitKey = userName + Constant.Character.UNDERLINE + serverLimit.key();
        RateLimiter rateLimiter = limiterMap.get(limitKey);
        if (rateLimiter == null) {
            rateLimiter = RateLimiter.create(serverLimit.limitPerSecond());
            // 缓存令牌
            limiterMap.put(limitKey, rateLimiter);
        }
        // 拿令牌
        boolean acquire = rateLimiter.tryAcquire(50, TimeUnit.MILLISECONDS);
        // 拿不到令牌直接抛出异常
        if (!acquire) {
            throw new ServerLimitedException();
        }
        return joinPoint.proceed();
    }
}

3. 完事

@GetMapping(value = "test")
@ServerLimit(key = "test", limitPerSecond = 5)
public BaseResponse test() {
    return BaseResponse.createSuccess();
}

4. 简简单单的限流方案,进阶的建议使用Redis实现~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值