我正在尝试跨线程实现速率限制。我的应用程序调用了一个外部 API,我们对 TPS 限制达成了硬性协议,超过该限制我的应用程序不应对 API 进行任何调用。对于每个新的客户请求,我的应用程序尝试 1) 使用 RateLimiter.tryAcquire() 获取许可并向外部 API 发送请求,或者 2) 如果无法获取许可,则请求失败。
为了确保在所有线程/客户请求中使用相同的 RateLimiter 实例,我使用 Spring 注释对其进行了@Autowired。在单元测试中,我能够断言在任何地方都调用了相同的速率限制器。
RateLimiter.create(1)
我正在尝试通过编写测试来验证是否满足速率限制。代码的简化版本如下所示:
void testRateLimiter() {
issueRequest();
issueRequest();
issueRequest();
}
Future<MyResponse> issueRequest() {
if (rateLimiter.tryAcquire()) {
//send request
final Callback callback =
this.okHttpCallbackFactory.createMeasuredCallback(this::onReply,
this.ResponseFuture::completeExceptionally);
this.httpClient.newCall(request).enqueue(callback);
System.out.println("Request Issued.");
} else {
//failed
this.ResponseFuture.completeExceptionally(exc);
System.out.println("Throttled.");
}
}
但观察到的输出是:
Request issued. 2021-Mar-18 12:34:52 AM
Request issued. 2021-Mar-18 12:34:52 AM
Throttled. 2021-Mar-18 12:34:52 AM
如果请求设置为 1 TPS,为什么允许两个请求?