
我们将使用Java的ScheduledExecutorService来实现一个简单的令牌桶算法(Token Bucket Algorithm),并结合一个自定义的服务类来处理第三方API调用。
首先,创建一个简单的限流器类:
import java.util.concurrent.*;
public class SimpleRateLimiter {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private Semaphore semaphore;
private final int permits;
private final long refillTimeMs;
public SimpleRateLimiter(int permits, long refillTimeMs) {
this.permits = permits;
this.refillTimeMs = refillTimeMs;
semaphore = new Semaphore(permits);
scheduleRefill();
}
private void scheduleRefill() {
scheduler.scheduleAtFixedRate(() -> {
semaphore.release(permits - semaphore.availablePermits());
}, refillTimeMs, refillTimeMs, TimeUnit.MILLISECONDS);
}
public boolean tryAcquire() {
return semaphore.tryAcquire();
}
}这个限流器每refillTimeMs毫秒会补充一定数量的许可(permits),从而控制请求速率。
接下来,创建一个服务类来模拟对第三方API的调用,并集成限流器:
import org.springframework.stereotype.Service;
@Service
public class ThirdPartyService {
private final SimpleRateLimiter rateLimiter;
public ThirdPartyService() {
// 每分钟最多10次请求
this.rateLimiter = new SimpleRateLimiter(10, 60_000);
}
public String fetchData() {
if (rateLimiter.tryAcquire()) {
// 模拟调用第三方API
return "Data from third-party API";
} else {
return "Rate limit exceeded, please try again later.";
}
}
}最后,在你的控制器中调用这个服务:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ThirdPartyController {
@Autowired
private ThirdPartyService thirdPartyService;
@GetMapping("/fetchData")
public String fetchData() {
return thirdPartyService.fetchData();
}
}为了实现简单的熔断器逻辑,我们可以维护一个状态变量来跟踪失败次数,并根据一定的条件决定是否触发熔断。
修改之前的ThirdPartyService类,增加熔断逻辑:
import org.springframework.stereotype.Service;
@Service
public class ThirdPartyService {
private final SimpleRateLimiter rateLimiter;
private volatile boolean circuitOpen = false;
private int failureCount = 0;
private static final int FAILURE_THRESHOLD = 5; // 失败阈值
private static final long CIRCUIT_OPEN_TIME_MS = 10_000; // 熔断打开时间
public ThirdPartyService() {
this.rateLimiter = new SimpleRateLimiter(10, 60_000);
}
public String fetchData() {
if (circuitOpen) {
return "Circuit is open, fallback response.";
}
if (!rateLimiter.tryAcquire()) {
return "Rate limit exceeded, please try again later.";
}
try {
// 模拟调用第三方API可能会抛出异常
if (Math.random() > 0.8) {
throw new RuntimeException("Third-party service is down");
}
resetFailureCount();
return "Data from third-party API";
} catch (Exception e) {
incrementFailureCount();
return handleFailure(e);
}
}
private void incrementFailureCount() {
failureCount++;
if (failureCount >= FAILURE_THRESHOLD) {
openCircuit();
}
}
private void resetFailureCount() {
failureCount = 0;
}
private void openCircuit() {
circuitOpen = true;
new Thread(() -> {
try {
Thread.sleep(CIRCUIT_OPEN_TIME_MS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
circuitOpen = false;
}).start();
}
private String handleFailure(Exception e) {
return "Fallback data due to service unavailability: " + e.getMessage();
}
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。