自学内容网 自学内容网

SpringBoot如何限制请求访问次数

在Spring Boot应用中限制请求访问次数可以通过几种不同的方法实现,如使用Rate Limiting中间件或自定义拦截器。以下是一些常见的实现方法:

方法1:使用Spring Boot内置的Rate Limiting工具

1.1 使用Bucket4j

Bucket4j是一个Java库,可以用来实现令牌桶算法的Rate Limiting。你可以通过以下步骤来集成Bucket4j:

步骤1:添加依赖

pom.xml中添加Bucket4j的依赖:

<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>6.2.0</version>
</dependency>

步骤2:创建配置类

创建一个Spring配置类来配置Rate Limiting:

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

@Configuration
public class RateLimiterConfig {

    @Bean
    public Bucket bucket() {
        Bandwidth limit = Bandwidth.classic(10, Refill.greedy(10, Duration.ofMinutes(1)));
        return Bucket4j.builder()
                .addLimit(limit)
                .build();
    }
}

步骤3:创建过滤器

创建一个过滤器来应用Rate Limiting:

import io.github.bucket4j.Bucket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class RateLimitFilter implements Filter {

    @Autowired
    private Bucket bucket;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (bucket.tryConsume(1)) {
            chain.doFilter(request, response);
        } else {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            httpResponse.getWriter().write("Too many requests");
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

步骤4:注册过滤器

application.propertiesapplication.yml中配置过滤器:

spring:
  web:
    filter:
      order: 1

方法2:使用Spring AOP实现Rate Limiting

通过Spring AOP(Aspect-Oriented Programming)也可以实现请求限制。

步骤1:创建自定义注解

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 RateLimit {
    int value();
}

步骤2:创建切面类

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class RateLimitAspect {

    private ConcurrentHashMap<String, Long> requestCounts = new ConcurrentHashMap<>();

    @Around("@annotation(rateLimit)")
    public Object rateLimit(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
        String key = joinPoint.getSignature().toShortString();
        requestCounts.putIfAbsent(key, 0L);

        long requests = requestCounts.get(key);
        if (requests >= rateLimit.value()) {
            throw new RuntimeException("Too many requests");
        } else {
            requestCounts.put(key, requests + 1);
            TimeUnit.MINUTES.sleep(1); // Reset the counter every minute
            return joinPoint.proceed();
        }
    }
}

步骤3:在需要限制的控制器方法上使用注解

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(10)
    @GetMapping("/resource")
    public String getResource() {
        return "This is a rate-limited resource";
    }
}

这两种方法都可以有效地限制Spring Boot应用中的请求访问次数。第一种方法使用Bucket4j库实现了令牌桶算法,第二种方法通过Spring AOP实现了自定义的Rate Limiting逻辑。可以根据你的具体需求选择合适的方法。


原文地址:https://blog.csdn.net/qq_46426180/article/details/140515449

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!