【问题标题】:Faster HTTP scraping per POST request?每个 POST 请求的 HTTP 抓取速度更快?
【发布时间】:2018-07-31 07:04:35
【问题描述】:

我正在编写一个 API,它为任何给定页面返回一个重定向数组:

router.post('/trace', function(req,res){

    if(!req.body.link)
        return res.status(405).send(""); //error: no link provided!

    console.log("\tapi/trace()", req.body.link);

    var redirects = [];

    function exit(goodbye){
        if(goodbye)
            console.log(goodbye);
        res.status(200).send(JSON.stringify(redirects)); //end
    }

    function getRedirect(link){
        request({ url: link, followRedirect: false }, function (err, response, body) {
            if(err)
                exit(err); 
            else if(response.headers.location){
                redirects.push(response.headers.location);
                getRedirect(response.headers.location);
            }
            else
                exit(); //all done!
        });
    }

    getRedirect(req.body.link);

});

这里是对应的浏览器请求:

$.post('/api/trace', { link: l }, cb);     

一个页面会很快发出大约 1000 个 post 请求,然后等待很长时间才能得到每个请求。

问题是对第 n 个请求的响应非常很慢。单个请求大约需要半秒钟,但最好我不能告诉快速服务器正在按顺序处理每个链接。我希望服务器发出所有请求并在 it 收到响应时做出响应。

我是否正确假设 express POST 路由器按顺序运行进程?我如何让它爆炸所有请求并在收到响应时传递响应?

【问题讨论】:

  • 您的问题到底是什么?从帖子中看不清楚
  • @djfdev 抱歉!我的问题是为什么这么慢/是在“开箱即用”的快速服务器上发布异步进程吗?

标签: node.js rest express post python-requests


【解决方案1】:

我的问题是为什么这么慢/是在“开箱即用”的快速服务器上发布异步进程吗?

您可能会惊讶地发现这可能首先是浏览器问题,而不是 node.js 问题。

浏览器将有最大数量的同时请求,它将允许您的 Javascript ajax 向同一主机发出,从一个浏览器到另一个浏览器会略有不同,但大约是 6 个。所以,如果您发出 1000 个请求,那么当时只有大约 6 个被发送。其余的在浏览器中排队等待先前的请求完成。因此,您的节点服务器可能不会同时收到 1000 个请求。您应该能够通过在 node.js 应用程序中记录传入请求来确认这一点。在收到第 1000 个请求之前,您可能会看到很长的延迟(因为它已被浏览器排队)。

以下是每个浏览器支持的给定主机的同时请求数量(截至几年前):Max parallel http connections in a browser?

我的第一个建议是打包一组从客户端向服务器发出的请求(一次可能 50 个),然后在一个请求中发送。这将使您的 node.js 服务器有足够的时间去咀嚼,并且不会违反浏览器对同一主机的连接限制。

至于 node.js 服务器,很大程度上取决于您在做什么。如果您在 node.js 服务器中所做的大部分工作只是联网,而不是需要 CPU 周期的大量处理,那么 node.js 在处理大量并发请求方面非常有效。如果您开始使用一堆 CPU(处理或准备结果),那么您可以从添加工作进程或使用 node.js 集群中受益。在您的情况下,您可能希望使用工作进程。当你的 node.js 服务器正在处理一堆工作时,你可以检查你的 CPU 负载,看看 node.js 使用的一个 CPU 是否接近 100%。如果不是,那么您不需要更多的 node.js 进程。如果是,那么您确实需要将工作分散到更多的 node.js 进程上才能更快。

在您的具体情况下,看起来您实际上只是在建立网络以收集 302 重定向响应。您的单个 node.js 进程应该能够非常有效地处理大量这些请求,因此问题可能只是您的客户端受到浏览器的限制。


如果您想向服务器发送大量请求(以便它可以处理尽可能多的请求),但又想在结果可用时立即返回,那就需要做更多的工作。

一种可行的方案是打开 webSocket 或 socket.io 连接。然后,您可以通过 socket.io 连接在一条消息中发送您希望服务器为您检查的大量 URL。然后,当服务器获得结果时,它可以发回每个单独的结果(用它对应的 URL 标记)。这样一来,您就可以在服务器处理一长串 URL 的情况下获得两全其美的效果,但能够在收到单个响应后立即发回。

注意,您可能会发现您可能希望同时从 node.js 服务器运行的出站 http 请求的数量也有上限。虽然现代版本的 node.js 不会像浏览器那样限制您,但您可能也不希望您的 node.js 服务器尝试同时运行 10,000 个请求,因为您可能会耗尽某种网络资源池。因此,一旦您克服了客户端瓶颈,您将希望在同时打开的请求的不同级别上测试您的服务器,以查看它在哪里表现最佳。这既是为了优化其性能,也是为了保护您的服务器免于尝试过度使用网络或内存资源并陷入错误状态。

【讨论】:

  • >您应该能够通过在您的 node.js 应用程序中记录传入请求来确认这一点......您是绝对正确的。我认为这是节点的“决定”,控制台日志(浏览器)是我认为已经提出的请求墙。我没有意识到这里还有另一层抽象。好的,您的“批量请求”想法是一个非常优雅的解决方案,我会实现它,非常感谢@jfriend00。
  • @Sam - 仅供参考,如果您需要一些帮助来在服务器上并行运行 N 个请求,以免运行太多,我之前就该主题写过几篇文章:@ 987654322@ 和 Promse.all() consumes all my RAM.
猜你喜欢
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 2020-07-01
相关资源
最近更新 更多