当前位置:   article > 正文

java sringboot 限制接口外部访问频率 每秒钟接口访问次数不得超过1次_spring boot 接口频率限制

spring boot 接口频率限制

在Spring Boot中,可以通过AOP和Redis实现接口访问频率限制,限制每秒钟接口访问次数不得超过1次的方法如下:

引入Redis依赖
在pom.xml文件中添加Redis依赖:

xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4

配置Redis
在application.properties文件中配置Redis连接信息:

properties

spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
  • 1
  • 2
  • 3
  • 4

编写AOP切面
创建一个切面类,用于限制接口的访问频率。在这个切面类中,我们需要使用Redis存储访问次数和时间戳,并根据设定的时间间隔和最大访问次数限制接口的访问频率。

import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Aspect
@Component
public class RequestLimitAspect {
    private static final int SECOND = 1;
    private static final int MAX_COUNT = 1;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Pointcut("@annotation(com.example.demo.annotation.RequestLimit)")
    public void requestLimit() {
    }
    @Around("requestLimit()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        String ip = request.getRemoteAddr();
        String uri = request.getRequestURI();
        String key = "req_limit:" + ip + ":" + uri;
        String countStr = redisTemplate.opsForValue().get(key);
        if (countStr == null) {
            redisTemplate.opsForValue().set(key, "1", SECOND, TimeUnit.SECONDS);
        } else {
            int count = Integer.parseInt(countStr);
            if (count >= MAX_COUNT) {
                response.setStatus(429);
                return "Too many requests";
            }
            redisTemplate.opsForValue().set(key, String.valueOf(count + 1), SECOND, TimeUnit.SECONDS);
        }
        return joinPoint.proceed();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

在上述代码中,我们首先使用@Autowired注解注入了RedisTemplate对象,该对象用于访问Redis数据库。然后,我们使用@Pointcut注解定义了一个切点requestLimit(),该切点表示被@RequestLimit注解标记的方法。接着,我们使用@Around注解定义了一个环绕通知,在被切入的方法执行前后执行该通知。在该通知中,我们首先获取请求的IP地址和URI,然后根据这些信息构建Redis的key值。如果该key值不存在,则将访问次数设置为1,并设置过期时间为1秒钟。如果该key值存在,则获取访问次数,如果访问次数超过1次,则返回429状态码和提示信息。否则,将访问次数加1,并将其存储到Redis中。
4. 添加自定义注解
创建一个自定义注解@RequestLimit,用于标记需要限制访问频率的方法:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLimit {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在接口方法上添加注解
在需要限制访问频率的接口方法上添加@RequestLimit注解:

@RestController
public class HelloController {
    @RequestLimit
    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在以上实现中,我们使用AOP和Redis实现了每秒钟接口访问次数不得超过1次的接口访问频率限制。具体实现可以根据实际需求进行调整。需要注意的是,以上代码可能会抛出Throwable异常,需要进行处理或抛出。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/874267
推荐阅读
相关标签
  

闽ICP备14008679号