接口限流是指在系统中对接口进行限制访问 , 以保护系统不被过载或异常流量所影响 。这通常是为了防止DDoS攻击或其他类型的恶意流量攻击 , 以及确保系统的稳定性和可靠性 。环境:Springboot3.0.5
概述接口限流是指在系统中对接口进行限制访问 , 以保护系统不被过载或异常流量所影响 。这通常是为了防止DDoS攻击或其他类型的恶意流量攻击 , 以及确保系统的稳定性和可靠性 。
接口限流可以采取多种方法 , 包括:
- 计数器:记录每个接口的访问次数 , 如果超过预设的限制 , 则限制对该接口的访问 。
- 速率限制:限制每个接口的访问速率 , 例如每秒请求数 。
- 滑动窗口算法:记录一段时间内每个接口的访问次数 , 并根据这些数据进行限流 。
- 漏桶算法:限制一段时间内的总访问次数或总请求数 , 无论接口是否被频繁访问 。
- 基于流的限流:根据网络流量进行限流 , 例如限制每个IP地址的流量 。
限流实现方案Guava实现接口限流
@Testpublic void testWithRateLimiter() {long start = System.currentTimeMillis() ;// 每秒最多接受10个请求RateLimiter limiter = RateLimiter.create(10.0) ;for (int i = 0; i < 10; i++) {// 如果没有可用的将会被阻塞limiter.acquire() ;System.out.println("execution bussiness invoke...") ;TimeUnit.SECONDS.sleep(1) ;}long end = System.currentTimeMillis() ;System.out.println((end - start) + "ms") ;}2. 通过Spring Cloud Gateway在Spring Cloud Gateway中提供了RequestRateLimiterGatewayFilterFactory过滤器 , 我们可以通过配置该过滤器来实现限流 , 该过滤默认提供了基于redis实现的RedisRateLimiter 。我们可以通过自定义RateLimiter实现自己的限流方案 。spring:cloud:gateway:routes:- id: testuri: http://localhost:8082filters:- name: RequestRateLimiterargs:key-resolver: '#{@packKeyResolver}'redis-rate-limiter.replenishRate: 1redis-rate-limiter.burstCapacity: 33. Resilience4j在该库中提供了限流的支持 , 我们可以通过编程的方式也可以直接通过注解的方式实现 。具体查看Resilience4j的官网都有介绍 。
- 自定义
自定义接口限流接下来通过一个注解结合Redis实现简单基于计数器的方法实现接口的限流 。
依赖配置
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>配置spring:data:redis:host: localhostport: 6379password: 123123database: 12lettuce:pool:maxActive: 8maxIdle: 100minIdle: 10maxWAIt: -1- 自定义注解
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface AccessLimit {// 单位时间:秒long seconds() default 1;// 单位时间内限制访问次数int count() default 10 ;}- 拦截器
@Componentpublic class AccessLimitInterceptor implements HandlerInterceptor {@Resourceprivate StringRedisTemplate stringRedisTemplate ;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 只针对@Controller(RequestMAppingHandlerMapping)的接口if (handler instanceof HandlerMethod handlerMethod) {Method method = handlerMethod.getMethod() ;// 具备AccessLimit注解的才进行拦截AccessLimit accessLimit = method.getDeclaredAnnotation(AccessLimit.class) ;if (accessLimit != null) {// 获取注解配置的参数long seconds = accessLimit.seconds() ;int count = accessLimit.count() ;if (seconds > 0 && count >= 0) {String key = request.getRemoteAddr() + ":" + request.getRequestURI() ;String value = https://www.isolves.com/it/cxkf/jiagou/2023-08-21/this.stringRedisTemplate.opsForValue().get(key) ;System.out.println("当前为:" + value) ;if (value == null) {this.stringRedisTemplate.opsForValue().set(key, String.valueOf(count - 1) , seconds, TimeUnit.SECONDS) ;return true ;} else {int c = Integer.valueOf(value) ;if (c
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Springboot默认的错误页是如何工作及工作原理你肯定不知道?
- 如何通过数据层的现代化来消解数字化转型的四个误区
- 一个唱红脸 一个唱白脸分别代表什么 白脸分别代表什么
- 一个人在家时注意事项
- 赵丽颖baby同时现身商场,一个高贵如公主一个穿衣低俗上不了台面
- 私交混乱还男女通吃?2次被传吸毒,张一山的“瓜”真是一个比一个猛!
- 为了一个戏子,连特警都出动了,手拉手组成人墙为其开路
- 安缦是什么意思 安缦是什么意思?
- 一个人必有后福的3个征兆,真的很准
- 让你成为“中年油腻女”的三大罪魁祸首,中一个就显老十岁
