当用户在早上运行时,数千人使用的 JAVA 7 离线软件会自动将备份发送到云端。每个发送的备份都会消耗服务器带宽。见下图:
可以注意到,在 08:15 AM 和 09:45 AM 之间形成了一个峰值。这是因为大多数用户在此时间间隔内运行软件。
我们需要更改软件,使其每 10 分钟向云端发送一次备份。这将大大增加带宽消耗,我们担心会达到某个限制,因为许多用户在同一高峰时间运行该软件。
作为解决方法,我们计划随机推迟第一次备份到服务器。但是,我们不认为这是一个好的解决方案。
这类问题常见吗?有没有标准的解决方案?
这是我们考虑如何做的算法,但我们不相信这是一个好的解决方案:
new Thread(new Runnable(){
@Override
public void run(){
String hhmmNow = new SimpleDateFormat("HH:mm")
.format(Calendar.getInstance().getTime());
if( hhmmNow.compareTo("08:15")>=0 && hhmmNow.compareTo("09:45")<=0 ){
Thread.sleep(new Random().nextInt(3600000)); //Sleep from 0 to 1h
}
while(true){
sendBackupToTheCloud();
Thread.sleep(600000); //Sleep 10 minutes
}
}
}).start();
编辑: 根据 Mcdowella 的建议更改为以下解决方案:
new Thread(new Runnable(){
@Override
public void run(){
int periodicity = 10 * 60 * 1000;
//Randon sleep between 0 and 10 minutes to
//distribute backups within the ten-minute interval.
Thread.sleep(new Random().nextInt(periodicity));
//Send new backup to server every 10 minutes
while(true){
sendBackupToTheCloud();
Thread.sleep(periodicity);
}
}
}).start();
最佳答案
有几种不同的方法可以解决这个问题。您可以执行一个略显冗长的协议(protocol),其中客户端首先请求进行备份并等待服务器响应服务器以允许它们上传数据,从而允许服务器在高负载时对某些客户端进行排队。
执行此操作的一种方法是发送 408 请求超时,然后编写客户端以在延迟后重试。
另一个想法是使用明确的 thread pool用于处理请求,以便在任何给定时间对正在处理的客户端数量有保证的限制。通常,大多数 Web 服务器都会有一种配置方式,例如 maxThreads option on Tomcat。 .
如问题中所建议的那样,随机化可能不是一个好主意,因为分布式系统往往会提供非常大的样本量,因此即使看似罕见的事件也变得不可避免。
关于java - 延迟访问服务器以尽量避开高峰时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45119310/