如何处理ThreadPool达到服务器连接限制

时间:2016-11-30 16:16:37

标签: android multithreading design-patterns threadpool

我可以在这里问一个设计模式问题。

在Android上,我使用线程池打开8个线程来下载一些文件。

    try {
        ExecutorService pool = Executors.newFixedThreadPool(8);
        for (int i = 0; i < someList.size(); i++) {
            pool.submit(new DownloadJsonTask(someList.get(i), context));
        }
        pool.shutdown();
        pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    } catch (Exception e) {
    }

我注意到如果我使用一个线程逐个下载,那么我很难下载失败,但如果我使用8个线程,那么我有时会下载失败。我不是服务器/网络人员,所以我不太详细,但我猜测服务器正在设置一个设备(或一个IP地址)的限制,试图连接多个连接。

如果这是原因,那么我该如何设计代码来克服这个问题呢?我已经实现了在失败之前尝试下载3次。它确实似乎已经修复了它#34;现在&#34;。但是,我知道我的代码不健全,并且可能在某一时刻失败。

我想,我不会是第一个面临这个问题的人。我想知道围绕这个问题的强有力的解决方案。

我能想到的解决方案:
- 在失败之前尝试下载至少3次 - 一旦失败,然后尝试睡眠一段随机时间。因此,失败的线程不会同时醒来并再次失败 - 如果服务器抛出某种独特的消息,例如服务器忙,则重新尝试无限制(?)(大量)次。

我还没有实现上述可能的解决方案。我想首先了解常见/最佳解决方案并花时间实施它。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

这个问题是基于意见的。我就此分享了我的观点。

理想情况下,如果您可以检查服务器日志并发现服务器端的内容应该修复,那么您应该首先执行此操作。

除此之外,即使客户端和服务器能够多线程并处理并发,也总会出现网络故障。也就是说,你应该在你的客户端有一个重试机制。

有关重试政策的一些设计要点

  1. 保持重试尝试可配置,而不是将其修复为3.(您可以在分析和测试时尝试正确的尝试次数)
  2. 请尝试exponential backoff
  3. ,而不是随意睡觉
  4. 我们可以向用户标记一条消息,以便稍后在指数退避重试后再次尝试,而不是无限次重试。 (类似于&#39;网站负载。请在一段时间后尝试&#39;)。
  5. 查看为您重试的库。像this
  6. 之类的东西
  7. 网络带宽也可能是导致下载失败的原因。您可以监控网络速度和类型(WiFi,LTE,3G)等,并决定是否下载或安排以后。
  8. 另一篇文章here

    希望这有帮助。