为什么node.js一次只处理六个请求?

我们有一个node.js服务器,它实现了一个REST API作为一个中央服务器的代理,这个服务器有一个稍微不同的,不幸的是不对称的REST API。

我们的客户端运行在各种浏览器中,要求节点服务器从中央服务器获取任务。 节点服务器从中央服务器获得所有任务ID的列表并将其返回给客户端。 然后,客户端通过代理为每个ID创build两个REST API调用。

据我所知,这些东西都是asynchronous完成的。 在控制台日志中,当我启动客户端时,它看起来像这样:

Requested GET URL under /api/v1/tasks/*: /api/v1/tasks/ 

这需要几秒钟才能从中央服务器获取列表。 一旦得到响应,服务器就会很快地把这个消息发送出去:

 Requested GET URL under /api/v1/tasks/id/:id :/api/v1/tasks/id/438 Requested GET URL under /api/v1/workflow/id/:id :/api/v1/workflow/id/438 Requested GET URL under /api/v1/tasks/id/:id :/api/v1/tasks/id/439 Requested GET URL under /api/v1/workflow/id/:id :/api/v1/workflow/id/439 Requested GET URL under /api/v1/tasks/id/:id :/api/v1/tasks/id/441 Requested GET URL under /api/v1/workflow/id/:id :/api/v1/workflow/id/441 

然后,每当有一对这样的请求得到中央服务器的结果时,另外两条线就会很快地被删除。

所以看来我们的node.js服务器只愿意一次发出六个请求。

Node本身没有强加TCP连接限制。 (整体来说,它是高度并发的,可以同时处理数千个连接。)您的操作系统可能会限制TCP连接。

更有可能是你的后端服务器受到某种限制,或者你正在达到内置HTTP库的连接限制,但是如果没有关于该服务器或者你的Node实现的更多细节,很难说。

Node内置的HTTP库 (显然是任何build立在它之上的库)都会维护一个连接池(通过Agent类),以便它可以使用HTTP保持活动。 这有助于在向同一服务器运行多个请求时提高性能:而不是打开TCP连接,发出HTTP请求,获取响应,closuresTCP连接并重复; 新的请求可以在重用的TCP连接上发出。

在节点0.10和更低版本中,默认情况下,HTTP代理将只打开5个同时连接到单个主机。 你可以很容易的改变它(假设你已经require HTTP模块为http

 http.globalAgent.maxSockets = 20; // or whatever 

节点0.12将默认的maxSocketsInfinity

您可能希望保留某种连接限制。 您不希望在一秒之内完全淹没您的后端服务器,并且数百个HTTP请求 – 性能最好的情况可能会比代理的连接池发挥作用,从而限制请求以避免超载服务器。 最好的办法是运行一些实验,看看你的情况下最佳的并发请求数。

但是,如果您确实不想连接池,则可以完全绕过池 – 在请求选项中将agent发送到false

 http.get({host:'localhost', port:80, path:'/', agent:false}, callback); 

在这种情况下,并发HTTP请求绝对没有限制。

这是浏览器中并发连接数量的限制:

在stream行的浏览器中允许多less个并发的AJAX(XmlHttpRequest)请求?

我已经提出了其他答案,因为他们帮助我诊断问题。 线索是节点的套接字限制是5,而我一次只能获得6个。 6是Chrome的限制,这是我用来testing服务器。

你如何从中央服务器获取数据? 使用http模块进行HTTP请求时,“节点不限制连接”并不完全准确。 以这种方式进行的客户端请求使用http.globalAgent实例,并且每个http.Agent都有一个名为maxSockets的设置,该设置确定代理可以向任何给定主机打开多less个套接字; 这默认为5。

因此,如果您使用http.requesthttp.get (或依赖这些方法的库)从中央服务器获取数据,则可以尝试更改http.globalAgent.maxSockets的值(或者修改该设置无论你使用的是什么http.Agent实例)。

看到:

  • http.Agent文档
  • agent.maxSockets文档
  • http.globalAgent文档
  • 您可以传递给http.request选项,包括一个agent参数来指定您自己的代理

我在服务器上看到了同样的问题。 它只处理4个请求。 正如已经解释的,从0.12的maxsockets默认为无穷大。 这轻而易举地压倒了服务器。 限制请求说10

 http.globalAgent.maxSockets = 20; 

解决了我的问题。

你确定它只是将结果返回给客户端吗? 节点在一个线程中处理一切。 所以,如果你做了一些奇特的反应parsing或其他任何不会产生,那么它会阻止你的请求。