如何限制 Java 中的带宽?理论:实现:

2022-09-05 00:37:31

我编写了一个Java调度程序,每小时使用:

new SAXBuilder().build(new URL(xxx));

HttpConnection.connect(new URL(xxx)); // jsoup library code

以获取一个大的 XML/HTML 文件。

我的服务器最大带宽限制为2Mb。

当这个Java调度代码运行时,我使用超过2Mb的带宽。(查看)

因此,每次用户访问我的服务器时,它都太慢了。

如何限制我的 Java 计划以使用较低的带宽?(例如 500K 位)

我正在使用Ubuntu服务器。


答案 1

没有优雅的方法来做到这一点。

一种简单但不优雅的方法是编写一个 Java 流包装器,用于限制从包装的流中读取字节的速率。例如,如果要限制为每秒 1000 字节,则可以按如下方式实现该方法:int read()

Stream in;
long timestamp = System.currentTimeInMillis();
int counter = 0;
int INTERVAL = 1000; // one second
int LIMIT = 1000; // bytes per INTERVAL

...

/**
 * Read one byte with rate limiting
 */
@Override
public int read() {
    if (counter > LIMIT) {
        long now = System.currentTimeInMillis();
        if (timestamp + INTERVAL >= now) {
            Thread.sleep(timestamp + INTERVAL - now);  
        }
        timestamp = now;
        counter = 0;
    }
    int res = in.read();
    if (res >= 0) {
        counter++;
    }
    return res;
}

值得注意的是,像这样的节流速率既有消极的影响,也有积极的影响。消极方面:

  • 它将服务器端的资源束缚更长时间。在本例中,我们谈论的是处理下载的 Java 线程,内核空间中的内存用于缓冲接收到的网络数据包,直到应用程序读取它们。

  • 它还可能导致更多的网络流量。问题在于,这种限制会破坏数据包的顺畅流动。服务器将仅缓冲相对较少数量的数据包,当超过该数量时,它必须告诉客户端暂时停止。这需要额外的信令数据包(ACK),并且在此过程中可能会丢弃数据包。最终,这些数据包将需要重新传输。


答案 2

理论:

令牌存储桶算法是一种限制下载带宽的方法。你应该阅读这篇文章 :它解释了这个算法的使用。

实现:

RateLimiter from Google Guava

Google Guava 22.0包括一个RateLimiter类,但它仍处于测试阶段。

从 API 文档:

例如,假设我们有一个要执行的任务列表,但我们不希望每秒提交超过 2 个:

final RateLimiter rateLimiter = RateLimiter.create(2.0); // rate is "2 permits per second"
  void submitTasks(List<Runnable> tasks, Executor executor) {
    for (Runnable task : tasks) {
      rateLimiter.acquire(); // may wait
      executor.execute(task);
    }
  }

作为另一个例子,假设我们生成一个数据流,并且我们希望将其限制为每秒5kb。这可以通过要求每个字节的许可证,并指定每秒5000个许可证的速率来实现:

final RateLimiter rateLimiter = RateLimiter.create(5000.0); // rate = 5000 permits per second
  void submitPacket(byte[] packet) {
    rateLimiter.acquire(packet.length);
    networkService.send(packet);
  }

TimedSemaphore from Apache Commons Lang v3

Apache Commons Lang v3包含一个TimedSemaphore类,可用于实现速率限制。


推荐