我对网络爬虫相当有经验,但是,这个问题与性能和规模有关。我需要在一段时间内请求和抓取 150,000 个 url(大多数 url 每 15 分钟一次,这使得每分钟大约有 10,000 个请求)。这些页面有相当多的数据(每页大约 200kb)。这 150,000 个网址中的每一个都存在于我们的数据库 (MSSQL) 中,并带有上次抓取日期的时间戳以及一个时间间隔,以便我们知道何时再次抓取。
这就是我们获得额外一层复杂性的地方。他们确实有一个 API,每次调用最多允许 10 个项目。我们需要的信息部分只存在于API中,部分只存在于网页中。所有者允许我们进行网络调用,并且他们的服务器可以处理它,但是,他们无法更新其 API 或提供直接数据访问。
所以流程应该是这样的:从数据库中获取10条间隔已过且需要爬取的记录,然后点击API。然后,这批 10 个项目中的每个项目都需要自己单独的 Web 请求。一旦请求返回 HTML,我们就会解析它并更新数据库中的记录。
我有兴趣获得一些有关处理基础设施的正确方法的建议。假设多服务器环境的一些业务需求:
- 一旦 URL 记录可供抓取,我们希望确保它仅由单个服务器抓取和运行。如果两个服务器同时检查并运行它,它可能会损坏我们的数据。
- 工作负载可能会有所不同,目前为 150,000 条网址记录,但可能会更低或更高。虽然我预计每天的变化不会超过 10%,但拥有某种自动缩放功能会很好。
- 每个请求返回 HTML 后,我们需要解析它并使用各个数据片段更新数据库中的记录。一些主机提供商允许免费传入数据,但对传出数据收费。因此,理想情况下,请求网页然后解析数据的代码库也可以直接进行 SQL 访问。 (与微服务方法相反)
类似多服务器阻塞集合(Azure 队列?)、自动缩放轮询队列的 VM、单个数据库主机服务器(也由向用户显示数据的 MVC 应用程序查询)。 非常感谢任何建议或批评。
最佳答案
消息传递
我同意 Evandro 的评论,并将探索事件中心的服务总线消息队列,以加载要由计算节点处理的队列。消息队列支持记录锁定,根据您的描述,这可能很有吸引力。
计算选项
我也同意 Azure Functions 将为扩展计算/处理操作(调用 API 和抓取 HTML)提供一个良好的平台。此外,Azure Functions 可以由消息队列、事件中心或事件网格触发。 [注意:事件网格允许您通过持久消息传递连接各种 Azure 服务(发布/订阅)。因此,它可能在您的场景中发挥有用的中间人作用。]
计算的另一个选项可能是 Azure 容器实例 (ACI),因为您可以按需启动容器来处理您的记录。它不具有与 Functions 相同的自动缩放功能,并且也不支持直接绑定(bind)操作。
数据处理问题(入口/导出)
事实上,Azure 不会对数据传入收费,但任何离开 Azure 的数据都会在每月初始 5 GB 后收取传出费用。 [https://azure.microsoft.com/en-us/pricing/details/bandwidth/]
您应该能够让 Azure Functions 处理调用 API、抓取 HTML 并写入数据库。您可能必须将它们分解为单独的函数,但您可以直接或使用 LogicApp 将函数轻松链接在一起。
关于sql-server - 每分钟 10,000 个 HTTP 请求性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50478509/