如何限制Java中的带宽?

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

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

要么

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

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

我的服务器最大带宽限制是2Mbits。

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

所以每次用户访问我的服务器时都会太慢。

如何限制Java计划使用较低的带宽? (例如500Kbits)

我正在使用Ubuntu服务器。

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

一种简单但不优雅的方法是编写一个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),并且可能在该过程中丢弃数据包。 最终,需要重新传输这些数据包。

理论:

令牌桶算法是一种限制下载带宽的方法。 您应该阅读本文 :它解释了此算法的用法。

实现:

来自Google Guava的RateLimiter

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

从api文档:

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

 final RateLimiter rateLimiter = RateLimiter.create(2.0); // rate is "2 permits per second" void submitTasks(List 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); } 

来自Apache Commons Lang v3的TimedSemaphore

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

一种可能的解决方案是使用限制带宽的代理服务器 。 如果你想要一个完整的java解决方案,你可以在这里使用一个简单的套接字java代理服务器,并使用Thread.sleep或任何其他方式减慢来自流进程的读/写。

看一下这个post: http : //httpcomponents.10934.n7.nabble.com/throttlling-download-traffic-td18329.html

此外,如果您使用apache httpclient,您可以将其配置为使用gzip压缩并节省一些带宽。 特别是对于xml,你应该期望通过这种方式传输更少的字节。