【问题标题】:How Many Java HttpURLConnections Should I Be Able to Open Concurrently?我应该能够同时打开多少个 Java HttpURLConnections?
【发布时间】:2009-09-04 22:33:24
【问题描述】:

我正在编写一个多线程 Java 网络爬虫。根据我对网络的了解,当用户加载网页时,浏览器会请求第一个文档(例如 index.html),当它接收到 HTML 时,它会找到需要包含的其他资源(图像、CSS、JS ) 并同时请求这些资源。

我的爬虫只请求原始文档。出于某种原因,我不能让它每 5 秒刮掉超过 2 到 5 页。我正在为我正在制作的每个 HttpURLConnection 创建一个新线程。看来我应该能够每秒至少抓取 20-40 页。如果我尝试启动 100 个线程,我会疯狂地获得 I/O 异常。有什么想法吗?

【问题讨论】:

  • 请考虑许多服务器对同一 IP 的访问设置了限制。在请求之间至少等待半秒或一秒是爬虫的标准做法。还可以查看archive.org 的爬虫Heritrix。它是开源的,用 Java 编写。非常好。

标签: java web-crawler screen-scraping


【解决方案1】:

看看你的代码是个好主意,因为你可能做了一些小错误并且破坏了你的爬虫,但作为一般的经验法则,异步 IO 远远优于 HttpURLConnection 提供的阻塞 IO。异步 IO 允许您在单个线程中处理所有处理,并且所有实际 IO 都由操作系统自行完成。

要通过异步 IO 实现 HTTP 协议的良好实现,请查看 Apache's HTTP core。查看此类客户端的示例here

【讨论】:

    【解决方案2】:

    有关您收到的 IOException 类型的详细信息可能会很方便。有几种可能性需要考虑。

    • 超出打开文件描述符限制(套接字过多)。
    • 由于打开到给定服务器的连接过多而拒绝连接。
    • 在能够处理任何数据之前获取过多数据(假设它阻塞 IO - 如果您向 100 台不同的服务器发出 100 个请求,您会突然收到大量数据 - HTTP GET 请求是小 - 响应可能不会。您可以自己有效地进行 DDoS)
    • 你在代码中犯了一个愚蠢的错误:)

    【讨论】:

      【解决方案3】:

      线程或 HttpUrlConnections 的最佳数量取决于许多因素。

      • 如果您抓取一个不是您的所有者的外部网站,您应该只使用一个线程和延迟。在另一种情况下,网站可以检测到 DOS 攻击。这段时间爬取不同的网站是有意义的。
      • 如果是自己的网站,没有 DOS 检测,则取决于网络延迟。如果您的 LAN 中有 Web 服务器,那么使用您使用的 CPU 内核的双倍计数会很有帮助。如果 Web 服务器在 Internet 中,那么使用更多线程会很有帮助。但我觉得 100 个线程太大了。这可能会破坏您的网络服务器。网络服务器有多少个工人?

      【讨论】:

        【解决方案4】:

        哦,我希望您正在关闭()您从连接中获得的输入流。无论如何,它们都会在 Connection 的终结器中关闭,但这可能很容易在几秒钟后完成。我自己也遇到过这个问题,所以也许对你有帮助。

        【讨论】:

          猜你喜欢
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-15
          • 2012-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多