【问题标题】:Guava RateLimiter in JAVAJAVA中的番石榴速率限制器
【发布时间】:2021-03-17 22:29:40
【问题描述】:

我想以 5/秒的速率向外部 API 发送请求,如下所示:

//limit sending rate to 5 per second
      RateLimiter rateLimiter = RateLimiter.create(5);

然后我将这个 rateLimiter 传递给方法(通过 for 调用):

for(...){
    broadcastToken = sendTemplateService.sendBroadcastPetition(broadcastInput, rateLimiter);
}

在这个方法中我做了很多事情:

public BroadcastToken sendBroadcastPetition(BroadcastInput broadcastInput, RateLimiter rateLimiter) {
//do a lot of stuff
rateLimiter.acquire();
restTemplate.exchange(broadcastUrl, HttpMethod.POST, entity, String.class);
}

我的方法正确吗?我不希望整个方法每秒执行 5 次,我想要的是对 API 的调用最大为每秒 5 次。

这个 RateLimiter.create(5) 只会影响下一行?

【问题讨论】:

    标签: java guava rate


    【解决方案1】:

    速率限制是从RateLimiter 对象获取许可。您创建了一个RateLimiter,每秒最多授予 5 个许可。因此,假设您只有一个 RateLimiter,您每秒只能执行 rateLimiter.acquire() 5 次,因此您只能运行调用 restTemplate.exchange 5 次的下一行也是每秒。

    不过,将RateLimiter 传递给函数使用似乎有点奇怪。哪个类负责确保每秒只调用 5 次 restTemplate.exchange?如果它是sendBroadcastPetition 的类(不管它是什么),那么该类应该创建RateLimiter(或接受一个作为构造函数参数)并始终使用那个。现在的情况是,sendBroadcastPetition 的调用者可以通过每次传入不同的RateLimiter 来打破速率限制。如果是调用者负责执行速率限制,那么可以在调用 sendBroadcastPetition 之前调用 acquire 并且不要传递 RateLimiter

    【讨论】:

    • 但是如果我把“RateLimiter rateLimiter = RateLimiter.create(5)”放在“sendBroadcastPetition”里面,它不会在每次被外部调用时重新启动吗?
    • 是的。您想在包含sendBroadcastPetition 的任何类的构造函数中创建它。 sendBroadcastPetition 是静态方法吗?
    • 它是一个在spring中带有@Service标签的公共类。问题:你的意思是:“sendBroadcastPetition 的调用者可以打破速率限制”是如果我通过另一个具有另一个 RateLimiter 的类调用此方法。但在这种唯一的情况下,它不会打败它,对吧?
    猜你喜欢
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多