Node.js涉及HTTP调用的性能优化

时间:2014-05-27 02:07:30

标签: multithreading node.js performance rest

我有一个Node.js应用程序,它打开一个文件,扫描每一行,并为每一行做一个涉及Couchbase的REST调用。文件中的平均行数约为1200万到1300万。目前没有任何特殊设置我的应用程序可以在~24分钟内完全处理~100万条记录。我浏览了很多问题,文章和节点文档,但无法找到有关以下内容的信息:

  1. 哪个设置表示节点可以同时打开X个http连接/套接字?我可以改变它吗?
  2. 我不得不规范文件处理,因为文件读取比REST调用要快得多,所以一段时间后开放的REST请求太多而且它会阻塞系统并且内存不足...所以现在我读了1000行等待REST调用完成,然后恢复它(我正在使用暂停和恢复方法在流上做)有更好的替代方案吗?
  3. 我可以执行所有可能的优化,使其变得比这更快。我知道gc相关的配置可以防止应用程序频繁停止。
  4. 正在使用" cluster"模块推荐?它无缝地工作吗?
  5. 背景:我们有一个现有的java应用程序通过生成100个线程完全相同,并且它能够实现比当前节点对应物稍微更好的吞吐量。但是我想尝试节点,因为有问题的两个操作(读取文件并为每一行进行REST调用)看起来像节点应用程序的完美情况,因为它们都可以在节点中异步,而Java应用程序会对这些节点进行阻塞调用。 ..

    非常感谢任何帮助......

2 个答案:

答案 0 :(得分:4)

通常,您应该将Stack Overflow上的问题分解成碎片。既然你的问题都是相同的,我会回答它们。首先,让我从底部开始:

  

我们有一个现有的java应用程序通过生成100个线程完全相同...但我想尝试节点,因为有问题的两个操作...看起来像节点应用程序的完美情况,因为它们都可以在节点中异步Java应用程序对这些进行阻塞调用的地方。

异步调用和阻塞调用只是帮助您控制流量和工作负载的工具。您的Java应用程序使用100个线程,因此一次可能有100个东西。您的Node.js应用程序可能有可能一次执行1,000项操作,但某些操作将在单个线程上以JavaScript完成,而其他IO工作将从线程池中提取。在任何情况下,如果您调用的后端系统一次只能处理20件事,这一切都不重要。如果你的系统100%被利用,改变你的工作方式肯定不会加速它。

简而言之,异步制作不是速度的工具,它是管理工作量的工具。

  

哪个设置表示节点可以同时打开X个http连接/套接字?我可以改变吗?

的Node.js' HTTP客户端自动拥有代理,允许您使用保持活动连接。这也意味着您不会淹没单个主机,除非您编写代码来执行此操作。如文档中所述,http.globalAgent.maxSocket=1000是您想要的,http://nodejs.org/api/http.html#http_agent_maxsockets

  

我必须规范文件处理,因为文件读取比REST调用要快得多,所以一段时间后开放的REST请求太多而且它会阻塞系统并且内存不足...所以现在我读了1000行等待REST调用完成,然后恢复它(我正在使用暂停和恢复方法在流上执行)是否有更好的替代方法?

请勿使用.on('data')为您的信息流use .on('readable')。只有在您准备好时才能从流中读取。我还建议using a transform stream to read by lines

  

我可以执行所有可能的优化,以便它变得比这更快。我知道与gc相关的配置可防止应用程序频繁停止。

如果不对代码进行详细分析,就无法回答这个问题。阅读有关Node.js及其内部工作原理的更多信息。如果你花一些时间在这上面,那么适合你的优化就会变得清晰。

  

正在使用" cluster"模块推荐?它能无缝地工作吗?

仅在您无法充分利用硬件时才需要这样做。它无法清楚你的意思和#34;但就操作系统而言,每个过程都是它自己的过程,所以我不会打电话给#34;"无缝"

答案 1 :(得分:2)

默认情况下,节点对所有http请求使用套接字池,默认全局限制为每个主机5个并发连接(但这些连接将重新用于keepalive连接)。围绕此限制有几种方法:

  1. 创建您自己的http.Agent并在您的http请求中指定它:

    var agent = new http.Agent({maxSockets: 1000});
    http.request({
      // ...
      agent: agent
    }, function(res) { });
    
  2. 更改全局/默认http.Agent限制:

    http.globalAgent.maxSockets = 1000;
    
  3. 完全禁用池请求/连接重用请求:

    http.request({
      // ...
      agent: false
    }, function(res) { });