【问题标题】:Google RateLimiter not Working for counterGoogle RateLimiter 不适用于计数器
【发布时间】:2018-04-01 09:41:43
【问题描述】:

我有将呼叫限制为 100/s 的案例。

我正在考虑使用 Google Guava RateLimiter。我是这样测试的:-

int cps = 100;
    RateLimiter limiter = RateLimiter.create(cps);
for(int i=0;i<200;i++) {
   limiter.acquire();
   System.out.print("\rNumber of records processed = " + i+1);
}

但代码并没有停止在 100 条记录上,让 1 秒完成。我做错了吗?

【问题讨论】:

    标签: java guava throttling


    【解决方案1】:

    RateLimiter 工作正常。问题是你的输出被缓冲了,因为你不是每次都刷新它。通常,标准输出是行缓冲的。所以如果你写了

    System.out.println("Number of records processed = " + (i+1));
    

    您会在 100 处看到暂停。但是,您所拥有的:

    System.out.print("\r处理的记录数 = " + i+1);

    有两个问题。第一,“\r”不作为换行,不会引起flush;因此整个输出被缓冲并一次性打印到控制台。其次,您需要将 (i+1) 放在括号中。您将 i 附加到字符串,然后将 1 附加到结果字符串。

    【讨论】:

      【解决方案2】:

      除了@DodgyCodeException 关于输出刷新和连接+1 的建议之外,让我们运行此代码以确保您了解RateLimiter 的工作原理:

      final double permitsPerSecond = 1;
      RateLimiter limiter = RateLimiter.create(permitsPerSecond);
      final Stopwatch stopwatch = Stopwatch.createStarted();
      int i = 0;
      for (; i < 2 * permitsPerSecond; i++) {
        limiter.acquire();
      }
      System.out.println("Elapsed = " + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "ms");
      System.out.println("Number of records processed = " + i);
      

      (请注意,我将尝试次数设置为 permitsPerSecond 次数的两倍。)当您将 permitsPerSecond 设置为 1 时,您会看到:

      经过 = 1001 毫秒
      处理的记录数 = 2

      对于permitsPerSecond = 10;permitsPerSecond = 100;,它会接近(在数学意义上)2 秒的限制,因为第 11 次或第 101 次尝试等待在RateLimiter 中设置的限制:

      经过 = 1902 毫秒
      处理的记录数 = 20

      经过 = 1991 毫秒
      处理的记录数 = 200

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-25
        • 2013-04-17
        • 1970-01-01
        • 2013-10-30
        相关资源
        最近更新 更多