SpringBoot 限流实现:外部接口并发调用速度控制
可以使用 Spring Boot 的限流功能来限制对外部接口的并发调用速度。下面是一个简单的示例:
- 首先,需要添加以下依赖到你的
pom.xml文件中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
这里我们使用 Redis 来实现限流的功能。
- 创建一个自定义注解来标记需要限流的方法,例如:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
int value(); // 限流次数
int period(); // 限流时间间隔,单位为毫秒
}
- 创建一个切面类来实现限流的逻辑,例如:
@Aspect
@Component
public class RateLimitAspect {
@Autowired
private RedisTemplate<String, Integer> redisTemplate;
@Around("@annotation(rateLimit)")
public Object limit(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {
// 获取方法的签名和参数
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Object[] args = joinPoint.getArgs();
// 构造 Redis 的 key,可以使用方法名加上参数的组合作为唯一标识
String key = method.getName() + Arrays.toString(args);
// 获取当前时间戳
long currentTime = System.currentTimeMillis();
// 获取限流次数和时间间隔
int limit = rateLimit.value();
int period = rateLimit.period();
// 判断当前时间戳是否大于上次调用时间戳加上时间间隔,如果是则重置限流次数为 0
if (redisTemplate.opsForValue().get(key) == null || currentTime > redisTemplate.opsForValue().get(key) + period) {
redisTemplate.opsForValue().set(key, 0, period, TimeUnit.MILLISECONDS);
}
// 判断限流次数是否超过限制
if (redisTemplate.opsForValue().increment(key, 1) > limit) {
throw new Exception("接口调用频率过高,请稍后再试");
}
// 调用目标方法
return joinPoint.proceed(args);
}
}
- 在需要限流的方法上使用自定义注解,例如:
@RestController
public class MyController {
@RateLimit(value = 20, period = 2000)
@GetMapping("/api")
public String callExternalApi() {
// 调用外部接口的逻辑
...
}
}
这样,在并发调用 /api 接口时,如果超过了限定的调用次数和时间间隔,将会抛出异常,限制接口的调用速度。
原文地址: https://www.cveoy.top/t/topic/pbF7 著作权归作者所有。请勿转载和采集!