考虑到我将Guava ratelimiter与warmpup结合使用,我试图找出一种方法来计算在特定时间会发生多少QPS。我阅读了评论here,但对我来说仍然不清楚。希望这里有人可以为我澄清。

我的用例:

我称外部服务的上限为50 TPS。需要注意的是,我们称其为前500次,必须远低于50 TPS,之后才能恢复50 TPS。 (如果有比使用ratelimiter更好的解决方案,我很想听听!)

伪代码:

RateLimiter rateLimiter = RateLimiter.create(50.0, 10, minutes);
for (String customerId : customerList) {
    rateLimiter.acquire();
    // call external service
}


假设我们只用一个线程执行此操作。有没有一种方法可以计算给定时间的TPS(QPS)? 3分钟? 5分钟?等等

最佳答案

RateLimiterwarmupPeriod的冷(最小)速率是稳定(最大)速率的1/3(这是从RateLimiter.java:147-184中硬编码为coldFactor3.0得出的)。在饱和需求(即不间断的许可请求)下,该速率将以恒定速率增加,直到达到稳定(最大)速率为止。

由于这是linear equation,我们可以将其写为y = m * x + b形式,其中


y(又称为y(x)),是在饱和时间段(例如3分钟)内我们的预期QPS,
qps(t)是从最低(最低)到稳定(最高)的变化率,
m(或x)是饱和需求下的经过时间,并且
t是我们的寒冷(最低)率(稳定(最高)率的1/3)。


总的来说,我们有b其中qps(t) = (stableRate - coldRate) / warmupPeriod * saturatedPeriod + coldRate

因此,对于您的示例,我们可以在3分钟内获得预期的QPS:

qps(3) = (50.0 - 50.0/3.0) / 10.0 * 3.0 + 50.0/3.0 ~= 26.6666


这是Java的实现:

/**
 * Calculates the expected QPS given a stableRate, a warmupPeriod, and a saturatedPeriod.
 * <p>
 * Both specified periods must use the same time unit.
 *
 * @param stableRate      how many permits become available per second once stable
 * @param warmupPeriod    the duration of the period where the {@code RateLimiter} ramps up
 *                        its rate, before reaching its stable (maximum) rate
 * @param saturatedPeriod the duration of the period for which the {@code RateLimiter} has
 *                        been under saturated demand starting from a cold state
 * @return The expected QPS assuming saturated demand starting from a cold state
 */
public static double qps(double stableRate, double warmupPeriod, double saturatedPeriod) {
    if (saturatedPeriod >= warmupPeriod) {
        return stableRate;
    }
    double coldRate = stableRate / 3.0;
    return (stableRate - coldRate) * saturatedPeriod / warmupPeriod + coldRate;
}


请注意,在实践中,使用单线程将无法使coldRate = stableRate / 3的需求饱和,因此您的实际QPS将略低于预期,并且几乎(如果有的话)实际上不会达到稳定的(最大)速率。但是,使用多个线程将使您始终有待处理的许可请求并饱和需求。

10-07 16:46