Spring Boot 接口访问频率限制的实现详解
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
@Configuration
public class RateLimitConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "rate-limiting-locks");
}
@Bean
public HandlerInterceptorAdapter rateLimitingInterceptor(RedisLockRegistry lockRegistry) {
return new HandlerInterceptorAdapter() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
String key = request.getRequestURI();
try {
// 尝试获取锁,超时时间设置为1秒
var lock = lockRegistry.obtain(key);
if (lock.tryLock(1, TimeUnit.SECONDS)) {
// 如果获取锁成功,则更新访问计数器
// ...更新访问计数器的逻辑...
return true;
} else {
// 如果未能获取锁,则表示请求过多
response.sendError(HttpServletResponse.SC_TOO_MANY_REQUESTS);
return false;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return false;
}
}
};
}
}
这个代码实例展示了如何在Spring Boot应用中
评论已关闭