springboot环境+redis实现分布式限流

分布式限流,依赖redis

实现1个按秒限流的限流器,
知识点:自定义注解,切面,注解的使用

源码

1.创建自定义注解 RateLimit

首先,我们定义一个自定义注解 RateLimit,它包含 code 和 limit 属性。

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RateLimit {
    String code();
    int limit();
}

2.创建切面处理注解逻辑

接下来,我们使用 Spring AOP 来创建一个切面,处理 RateLimit 注解的逻辑。在这个示例中,我们假设你使用的是 Spring 框架。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

@Aspect
@Component
public class RateLimitAspect {

    private Jedis jedis;

    public RateLimitAspect() {
        // 初始化 Jedis 客户端
        this.jedis = new Jedis("localhost", 6379); // 请根据你的 Redis 配置进行调整
    }

    @Around("@annotation(rateLimit)")
    public Object around(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
        String key = rateLimit.code();
        int limit = rateLimit.limit();

        long currentCount = jedis.incr(key);

        if (currentCount == 1) {
            // 设置过期时间为 1 秒
            jedis.expire(key, 1);
        }

        if (currentCount > limit) {
            // 超过限流限制
            throw new RuntimeException("Rate limit exceeded");
        }

        return joinPoint.proceed();
    }
}

3.使用 RateLimit 注解

现在你可以在你的控制器或服务方法上使用 RateLimit 注解来进行限流。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class MyController {

    @RateLimit(code = "my-api", limit = 5)
    @GetMapping("/limited")
    public String limitedEndpoint() {
        return "This endpoint is rate limited!";
    }
}

4.配置 Spring 应用

确保你的 Spring 应用配置了 AOP 支持。你可以在 Spring Boot 应用中通过在主类上添加 @EnableAspectJAutoProxy 注解来启用 AOP。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy
public class RateLimitApplication {

    public static void main(String[] args) {
        SpringApplication.run(RateLimitApplication.class, args);
    }
}

5. 依赖项

确保你的 pom.xml 文件中包含必要的依赖项:

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Starter AOP -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

    <!-- Jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>4.2.3</version>
    </dependency>
</dependencies>

总结

通过以上步骤,你已经实现了一个自定义注解 RateLimit,并使用 Jedis 实现了 Redis 分布式限流功能。这个示例展示了如何使用 Spring AOP 来处理注解逻辑,并将限流逻辑应用到特定的控制器方法上。你可以根据需要进一步扩展和优化这个实现。

posted @ 2024-09-03 14:01  SpecialSpeculator  阅读(104)  评论(0编辑  收藏  举报