使用 Semaphore 实现外部接口限速和异步调用

本文将介绍如何使用 Spring Boot 的 Semaphore 实现外部接口限速,并通过 @Async 注解实现异步调用,确保在并发调用时不超过接口的速率限制。

场景: 假设有一个外部接口,其限制为每秒最多 20 次请求,现在有 5 个方法需要并发调用该接口,每个方法每分钟需要调用 120 次。

解决方案:

  1. 创建 RateLimiter 类: 该类使用 Semaphore 实现限速功能。
import java.util.concurrent.Semaphore;

public class RateLimiter {
    private Semaphore semaphore;
    
    public RateLimiter(int maxPermits) {
        semaphore = new Semaphore(maxPermits);
    }
    
    public void acquire() throws InterruptedException {
        semaphore.acquire();
    }
    
    public void release() {
        semaphore.release();
    }
}
  1. 在 Spring Boot 配置类中创建 RateLimiter 的 Bean:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    public RateLimiter rateLimiter() {
        return new RateLimiter(20);
    }
}
  1. 创建包含外部接口调用逻辑的服务类:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class ExternalService {
    @Autowired
    private RateLimiter rateLimiter;
    
    @Async
    public void callExternalApi() throws InterruptedException {
        rateLimiter.acquire();
        
        // 调用外部接口的逻辑
        // ...
        
        rateLimiter.release();
    }
}
  1. 创建定时任务类,每分钟并发调用 5 个方法:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class ScheduledTask {
    @Autowired
    private ExternalService externalService;
    
    @Scheduled(fixedRate = 60000) // 每分钟执行一次
    public void execute() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            externalService.callExternalApi();
        }
    }
}

工作流程:

  • 每个方法在调用外部接口之前会先调用 rateLimiter.acquire() 获取令牌。
  • 如果令牌数量足够,则方法可以继续执行;否则,方法会等待直到获得令牌。
  • 在方法执行完成后,调用 rateLimiter.release() 释放令牌,以便其他方法可以获取。
  • 定时任务每分钟会并发调用 5 个方法,确保每个方法在调用外部接口之前都会进行限速。

注意:

  • Semaphore 的初始值 (即 maxPermits) 需要根据外部接口的速率限制进行设置。
  • 每个方法在调用外部接口后都需要释放令牌,否则会造成令牌不足,导致其他方法无法获取令牌。
  • 在实际应用中,可以根据需要调整 @Scheduled 注解的 fixedRate 属性,以及每个方法的调用次数。

通过以上步骤,即可使用 Semaphore 实现外部接口限速,并通过 @Async 注解实现异步调用,确保在并发调用时不超过接口的速率限制。

Spring Boot 使用 Semaphore 实现外部接口限速和异步调用

原文地址: https://www.cveoy.top/t/topic/pbQ9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录