【问题标题】:Java UrlConnection triggering "Connection reset" exceptions under high load. Why?Java UrlConnection 在高负载下触发“连接重置”异常。为什么?
【发布时间】:2012-02-02 17:30:00
【问题描述】:

我在 Linux (Ubuntu 10) 64 位服务器上使用 Java 从 Amazon S3 流式传输文件。

我为每个文件使用单独的线程,每个文件都会打开一个HttpURLConnection,它会同时下载和处理每个文件。

在我达到一定数量的流(通常大约 2-300 个并发流)之前,一切都运行良好。在此之后的不规则时间点,多个(例如 10 个)线程将开始同时遇到java.net.IOException: Connection reset 错误。

我正在限制下载速度,并且远低于 m1.large 实例的 250mbit/s 限制。所有其他服务器方面的负载也微不足道(例如 CPU、平均负载和内存使用情况都很好)。

这可能是什么原因造成的,或者我怎样才能找到它?

【问题讨论】:

  • 等一下,让我得到我的魔法 8 球 ;)
  • 好吧,或者您可以提供任何经验或建议,非常感谢;)
  • 可能是某个中间点限制了您的连接,比如公司防火墙。
  • 不存在防火墙,服务器在 Amazon EC2 上,直接连接到 S3
  • 由于您在 EC2 virt 上与 S3 通信,因此您应该将此问题发送给 Amazon 的 AWS 支持。您的连接断开可能有多种原因,他们可能能够通过他们可以访问的工具帮助您诊断问题。当您遇到可能的错误时,您可能还想获取一个 tcpdump 并查看那里是否有任何感兴趣的内容。

标签: java networking concurrency amazon-s3 ioexception


【解决方案1】:

猜测可能发生的事情并非易事,但这是一些提示,可能有些可能适用于您的上下文:

  • 你能检查你的 shell(linux bash /zsh 或任何其他),看看你是否提高了限制文件描述符数量的标准限制(但也包括套接字), man ulimit 与 bash shell
  • 您是否在 Java 代码中明确关闭了流?不关闭流可能会引发如此巧妙的问题
  • 尝试在 google 上进行 Linux TCP 内核调整,以尝试查看您的 ubuntu 服务器是否具有非常适合此类负载上下文的堆栈...

HTH 杰罗姆

【讨论】:

    【解决方案2】:

    由于并发连接数已达到限制,他们可能会在 VIP 处出现溢出问题。您可以减小尺寸并查看...

    【讨论】:

      【解决方案3】:

      这里的问题主要在于您的语言。高负载正在触发错误条件,错误条件导致异常。反之亦然。

      【讨论】:

      • 您能否详细说明您认为这是为什么?正如我所说,我在网络、CPU 和内存范围内都很好。
      • @robw 异常不会“触发”事情。它们由错误条件触发。这里的错误情况显然是过载。
      • 也许你误会了我。我很清楚例外是什么以及它们是如何工作的。您也可能是正确的,负载触发了这一点,但答案不仅仅是“少下载”。 m1.large 应该能够处理这么多的工作量。我想知道如何了解断线的确切原因并解决它们。
      • @robw 我没有说“少下载”,但根据您自己的帖子,它肯定与负载有关。可能您的操作系统连接太多。
      【解决方案4】:

      此类问题的一个相对常见的原因是中间代理(防火墙、负载平衡器)丢弃了它认为不活动(或寿命过长)的 HTTP 连接。 但除了这种一般可能性之外,EC2 肯定有其他人建议的更多问题。

      【讨论】:

        【解决方案5】:

        您可能用完了ephemeral ports。当许多短期连接快速打开和关闭时,这种情况会在负载下发生。标准 Java HttpURLConnection 不会为您提供设置正确套接字选项所需的灵活性。我建议使用Apache HttpComponents 项目,并设置像这样的选项...

        ... HttpGet httpGet = new HttpGet(uri); HttpParams 参数 = new BasicHttpParams(); params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 16 * 1000); // 16 秒 params.setParameter(CoreConnectionPNames.SO_REUSEADDR, true); // = HTTP_STATUS_CODE_300) { ...

        我省略了一些代码,例如 connectionManager 设置,但您可以从他们的文档中了解。

        [更新] 您还可以添加 params.setParameter(CoreConnectionPNames.SO_LINGER, 1); 以防止临时端口在回收之前徘徊。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-25
          • 1970-01-01
          • 2015-10-03
          • 2021-05-25
          • 2019-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多