做网站听的纯音乐,做企业网站前期需要准备什么资料,济南网站优化费用,公司名称注册查询官网入口目录
概述为什么需要接口访问频率限制常见的实现方式 基于过滤器的实现基于拦截器的实现基于第三方库Bucket4j的实现 实际代码示例 基于过滤器实现Rate Limiting基于拦截器实现Rate Limiting使用Bucket4j实现Rate Limiting 最佳实践 选择合适的限流算法优化性能记录日志和监控…目录
概述为什么需要接口访问频率限制常见的实现方式 基于过滤器的实现基于拦截器的实现基于第三方库Bucket4j的实现 实际代码示例 基于过滤器实现Rate Limiting基于拦截器实现Rate Limiting使用Bucket4j实现Rate Limiting 最佳实践 选择合适的限流算法优化性能记录日志和监控 总结
概述
接口访问频率限制是通过在一定时间内限制用户对接口的访问次数来实现的。常见的限流算法包括令牌桶算法Token Bucket、漏桶算法Leaky Bucket、固定窗口计数器Fixed Window Counter和滑动窗口计数器Sliding Window Counter等。在Spring Boot中我们可以通过多种方式来实现接口的限流如使用过滤器、拦截器或者借助第三方库。
为什么需要接口访问频率限制
防止恶意攻击通过限制接口的访问频率可以有效防止恶意用户或机器人频繁访问接口导致系统资源耗尽。提升系统稳定性在高并发场景下限流可以有效保护后端服务避免因流量过大而导致系统崩溃。提升用户体验合理的限流可以保障所有用户都能获得较好的服务质量避免个别用户过度使用资源。
常见的实现方式
基于过滤器的实现
过滤器是Java Web应用中常用的一种组件它可以在请求到达Servlet之前对请求进行预处理。通过在过滤器中实现限流逻辑可以对所有的HTTP请求进行统一的限流控制。
基于拦截器的实现
拦截器是Spring框架提供的一种处理器可以在请求处理之前和之后进行相关操作。相比于过滤器拦截器可以更加细粒度地控制请求适用于需要针对某些特定接口进行限流的场景。
基于第三方库Bucket4j的实现
Bucket4j是一个Java实现的高性能限流库它支持多种限流算法如令牌桶算法。通过使用Bucket4j可以轻松地在Spring Boot应用中实现复杂的限流逻辑并且它还提供了丰富的配置选项和统计功能。
实际代码示例
基于过滤器实现Rate Limiting
首先我们需要创建一个自定义的过滤器类并在其中实现限流逻辑。以下是一个示例代码
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;public class RateLimitingFilter implements Filter {private final ConcurrentMapString, Long requestCounts new ConcurrentHashMap();private static final long ALLOWED_REQUESTS_PER_MINUTE 60;Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化过滤器}Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpRequest (HttpServletRequest) request;HttpServletResponse httpResponse (HttpServletResponse) response;String clientIp httpRequest.getRemoteAddr();long currentTimeMillis System.currentTimeMillis();requestCounts.putIfAbsent(clientIp, currentTimeMillis);long lastRequestTime requestCounts.get(clientIp);if (TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - lastRequestTime) 1) {long requestCount requestCounts.values().stream().filter(time - TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - time) 1).count();if (requestCount ALLOWED_REQUESTS_PER_MINUTE) {httpResponse.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);httpResponse.getWriter().write(Too many requests);return;}}requestCounts.put(clientIp, currentTimeMillis);chain.doFilter(request, response);}Overridepublic void destroy() {// 销毁过滤器}
}然后在Spring Boot应用的配置类中注册这个过滤器
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class FilterConfig {Beanpublic FilterRegistrationBeanRateLimitingFilter loggingFilter(){FilterRegistrationBeanRateLimitingFilter registrationBean new FilterRegistrationBean();registrationBean.setFilter(new RateLimitingFilter());registrationBean.addUrlPatterns(/api/*);return registrationBean;}
}基于拦截器实现Rate Limiting
首先我们需要创建一个自定义的拦截器类并在其中实现限流逻辑。以下是一个示例代码
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;public class RateLimitingInterceptor implements HandlerInterceptor {private final ConcurrentMapString, Long requestCounts new ConcurrentHashMap();private static final long ALLOWED_REQUESTS_PER_MINUTE 60;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String clientIp request.getRemoteAddr();long currentTimeMillis System.currentTimeMillis();requestCounts.putIfAbsent(clientIp, currentTimeMillis);long lastRequestTime requestCounts.get(clientIp);if (TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - lastRequestTime) 1) {long requestCount requestCounts.values().stream().filter(time - TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - time) 1).count();if (requestCount ALLOWED_REQUESTS_PER_MINUTE) {response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);response.getWriter().write(Too many requests);return false;}}requestCounts.put(clientIp, currentTimeMillis);return true;}
}然后在Spring Boot应用的配置类中注册这个拦截器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;Configuration
public class WebConfig implements WebMvcConfigurer {Autowiredprivate RateLimitingInterceptor rateLimitingInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(rateLimitingInterceptor).addPathPatterns(/api/**);}
}使用Bucket4j实现Rate Limiting
首先在项目中引入Bucket4j依赖
dependencygroupIdcom.github.vladimir-bukhtoyarov/groupIdartifactIdbucket4j-core/artifactIdversion7.0.0/version
/dependency然后创建一个自定义的过滤器类并在其中实现限流逻辑
import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;public class Bucket4jRateLimitingFilter implements Filter {private final ConcurrentMapString, Bucket buckets new ConcurrentHashMap();Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化过滤器}Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpRequest (HttpServletRequest) request;HttpServletResponse httpResponse (HttpServletResponse) response;String clientIp httpRequest.getRemoteAddr();Bucket bucket buckets.computeIfAbsent(clientIp, this::newBucket);if (bucket.tryConsume(1)) {chain.doFilter(request, response);} else {httpResponse.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);httpResponse.getWriter().write(Too many requests);}}private Bucket newBucket(String clientIp) {return Bucket4j.builder().addLimit(Bandwidth.classic(60, Refill.greedy(60, Duration.ofMinutes(1)))).build();}Overridepublic void destroy() {// 销毁过滤器}
}然后在Spring Boot应用的配置类中注册这个过滤器
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class FilterConfig {Beanpublic FilterRegistrationBeanBucket4jRateLimitingFilter loggingFilter(){FilterRegistrationBeanBucket4jRateLimitingFilter registrationBean new FilterRegistrationBean();registrationBean.setFilter(new Bucket4jRateLimitingFilter());registrationBean.addUrlPatterns(/api/*);return registrationBean;}
}最佳实践
选择合适的限流算法
根据实际业务需求选择合适的限流算法例如
令牌桶算法适用于需要平滑突发流量的场景。漏桶算法适用于需要严格控制流量的场景。固定窗口计数器适用于对简单限流要求的场景。滑动窗口计数器适用于需要精确控制限流的场景。
优化性能
减少锁竞争在高并发环境下尽量减少锁的使用可以采用无锁数据结构或者线程安全的数据结构。缓存结果对于频繁访问的数据可以考虑进行缓存减少数据库查询的次数。异步处理对于耗时的操作可以考虑采用异步处理提高系统的响应速度。
记录日志和监控
记录访问日志记录每次接口访问的详细信息包括请求时间、IP地址、请求路径等。监控限流情况对限流情况进行监控及时发现和处理异常流量。报警机制设置限流报警机制当流量超过预设阈值时及时报警。
总结
本文详细介绍了在Spring Boot中实现接口访问频率限制的几种方法包括基于过滤器、拦截器和第三方库Bucket4j的实现。通过合理的限流策略可以有效防止恶意攻击提升系统的稳定性和用户体验。在实际应用中选择合适的限流算法和实现方式并结合业务需求进行优化是确保系统高效运行的关键。
希望本文能够帮助你更好地理解和实现Spring Boot中的接口访问频率限制。如果你有任何问题或建议欢迎在评论区留言讨论。