Java 延迟对服务器的访问以避免高峰时间

Java 延迟对服务器的访问以避免高峰时间,java,algorithm,optimization,bandwidth,Java,Algorithm,Optimization,Bandwidth,数千人使用的JAVA 7离线软件在用户早上运行时会自动向云发送备份。每次发送备份都会占用服务器带宽。见下表: 可以注意到,峰值形成于上午8:15至09:45之间。这是因为大多数用户在这段时间间隔内运行软件 我们需要更改软件,使其每10分钟向云发送一次备份。这将大大增加带宽消耗,我们担心我们会达到一些限制,因为许多用户在同一高峰时间运行该软件 作为一种解决方法,我们计划随机推迟对服务器的第一次备份。然而,我们不相信这是一个好的解决办法 这类问题常见吗?有标准的解决方案吗? 下面是我们如何考虑这

数千人使用的JAVA 7离线软件在用户早上运行时会自动向云发送备份。每次发送备份都会占用服务器带宽。见下表:

可以注意到,峰值形成于上午8:15至09:45之间。这是因为大多数用户在这段时间间隔内运行软件

我们需要更改软件,使其每10分钟向云发送一次备份。这将大大增加带宽消耗,我们担心我们会达到一些限制,因为许多用户在同一高峰时间运行该软件

作为一种解决方法,我们计划随机推迟对服务器的第一次备份。然而,我们不相信这是一个好的解决办法

这类问题常见吗?有标准的解决方案吗?


下面是我们如何考虑这样做的算法,但我们不相信这是一个好的解决方案:


有两种不同的方法可以解决这个问题。您可以执行一个稍微闲聊的协议,其中客户端首先请求执行备份,然后等待服务器响应,从而允许他们上载数据,从而允许服务器在高负载下对某些客户端进行排队

一种方法是发送408请求超时,然后写入客户端以在延迟后重试

另一个想法是使用显式方法来处理请求,这样在任何给定时间处理的客户机数量都有一个有保证的限制。通常,大多数web服务器都有一种配置方法,例如


随机化可能不是问题中提出的一个好主意,因为分布式系统往往会提供非常大的样本量,以至于即使看似罕见的事件也不可避免。

有几种不同的方法来解决这个问题。您可以执行一个稍微闲聊的协议,其中客户端首先请求执行备份,然后等待服务器响应,从而允许他们上载数据,从而允许服务器在高负载下对某些客户端进行排队

一种方法是发送408请求超时,然后写入客户端以在延迟后重试

另一个想法是使用显式方法来处理请求,这样在任何给定时间处理的客户机数量都有一个有保证的限制。通常,大多数web服务器都有一种配置方法,例如


随机化可能不是问题中提出的一个好主意,因为分布式系统往往提供非常大的样本量,以至于即使看似罕见的事件也不可避免。

不好。从繁忙时间开始,您的延迟用户可能最终成为峰值的最高点的服务器。有些用户即使在没有必要的时候也会被延迟

虽然随机化使峰值变平了一点,但这肯定不是个好主意。简单地询问服务器是否能够处理请求是简单而有效的。它不需要是一个单独的请求,HTTP Status
503 Service Unavailable
就是针对这种情况的。您的客户端应在几分钟后重试

虽然随机分布会使峰值变平,但询问服务器是随着时间推移实现完全恒定利用率的唯一方法


请注意,您当前的带宽低于1 Mb/s,这比my IP provider提供的标准私人家庭连接的带宽低一百倍。您可以使用负载平衡器,或者简单地让客户机从服务器池中进行选择,如果一台服务器的负载太大的话。但是,一台服务器很容易使磁盘带宽饱和,对于旧硬盘来说,这大约是50 MB/s=400 MB/s。

不好。从繁忙时间开始,您的延迟用户可能最终成为峰值的最高点的服务器。有些用户即使在没有必要的时候也会被延迟

虽然随机化使峰值变平了一点,但这肯定不是个好主意。简单地询问服务器是否能够处理请求是简单而有效的。它不需要是一个单独的请求,HTTP Status
503 Service Unavailable
就是针对这种情况的。您的客户端应在几分钟后重试

虽然随机分布会使峰值变平,但询问服务器是随着时间推移实现完全恒定利用率的唯一方法


请注意,您当前的带宽低于1 Mb/s,这比my IP provider提供的标准私人家庭连接的带宽低一百倍。您可以使用负载平衡器,或者简单地让客户机从服务器池中进行选择,如果一台服务器的负载太大的话。但是,一台服务器很容易使磁盘带宽饱和,对于一台旧的HDD,这种带宽大约为50 MB/s=400 MB/s。

一个应用程序发送到服务器的备份大小是多少?备份大小在500KB和4MB之间。如果数千用户将备份上载到同一台服务器,则可以。您应该考虑在服务器上使用负载均衡器。这样,您就不需要更改软件中的算法。或者,如果您仍然需要实施,那么在将备份上载到云之前,您应该请求服务器了解是否有足够的带宽供您上载。有一些方法可以通过编程检查服务器端的带宽如果您有日志告诉您用户何时上传某一天的备份,您可以使用这些日志计算出任何特定睡眠策略在该天的结果。我倾向于总是做一个随机的睡眠,但要让它最多10分钟。然后,每个用户都有可能在每10分钟重复一次的时间表内选择任何给定的时间段。@mcdowella您的评论帮了很多忙。我没有使用日志,而是使用当前存储的备份的总大小、每个用户的平均备份数和
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();
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();