我每小时写一个Java调度程序:
new SAXBuilder().build(new URL(xxx));
或
HttpConnection.connect(new URL(xxx)); // jsoup library code
获取大型XML / HTML文件。
我的服务器最大带宽限制是2Mbits。
当这个Java调度代码运行时,我使用超过2Mbits的带宽。 (check it out)
因此,每当用户访问我的服务器时,它都会太慢。
如何限制Java计划使用较低的带宽? (例如500Kbits)
我正在使用Ubuntu服务器。
答案 0 :(得分:15)
没有优雅的方法来做到这一点。
一种简单但不优雅的方法是编写一个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),并且可能在该过程中丢弃数据分组。最终,需要重新传输这些数据包。
答案 1 :(得分:15)
Token Bucket Algorithm是一种限制下载带宽的方法。 您应该阅读this article:它解释了此算法的使用。
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);
}
来自Apache Commons Lang v3的Apache Commons Lang v3包含一个TimedSemaphore类,可用于实现速率限制。
答案 2 :(得分:3)
可能的解决方案是使用限制带宽的代理服务器。如果你想要一个完整的java解决方案,你可以使用一个简单的套接字java代理服务器here,并使用Thread.sleep或任何其他方式减慢来自流进程的读/写。
答案 3 :(得分:0)
看一下这个主题:http://httpcomponents.10934.n7.nabble.com/throttlling-download-traffic-td18329.html
此外,如果您使用apache httpclient,您可以将其配置为使用gzip压缩并节省一些带宽。特别是对于xml,你应该期望以这种方式传输更少的字节。