为什么 node.js 一次只处理六个请求?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12060869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is node.js only processing six requests at a time?
提问by Almo
We have a node.js server which implements a REST API as a proxy to a central server which has a slightly different, and unfortunately asymmetric REST API.
我们有一个 node.js 服务器,它实现了一个 REST API 作为中央服务器的代理,中央服务器有一个稍微不同的,不幸的是非对称的 REST API。
Our client, which runs in various browsers, asks the node server to get the tasks from the central server. The node server gets a list of all the task ids from the central one and returns them to the client. The client then makes two REST API calls per id through the proxy.
我们的客户端运行在各种浏览器中,它要求节点服务器从中央服务器获取任务。节点服务器从中央服务器获取所有任务 ID 的列表,并将它们返回给客户端。然后客户端通过代理为每个 id 进行两次 REST API 调用。
As far as I can tell, this stuff is all done asynchronously. In the console log, it looks like this when I start the client:
据我所知,这些东西都是异步完成的。在控制台日志中,当我启动客户端时,它看起来像这样:
Requested GET URL under /api/v1/tasks/*: /api/v1/tasks/
This takes a couple seconds to get the list from the central server. As soon as it gets the response, the server barfs this out very quickly:
这需要几秒钟才能从中央服务器获取列表。一旦得到响应,服务器就会非常迅速地将其排除:
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
Then, each time a pair of these requests gets a result from the central server, another two lines is barfed out very quickly.
然后,每当一对这样的请求从中央服务器获得结果时,就会很快发出另外两行。
So it seems our node.js server is only willing to have six requests out at a time.
所以看起来我们的 node.js 服务器一次只愿意发出 6 个请求。
采纳答案by Almo
It's the limit on number of concurrent connections in the browser:
这是浏览器中并发连接数的限制:
How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?
流行浏览器中允许多少并发 AJAX (XmlHttpRequest) 请求?
I have upvoted the other answers, as they helped me diagnose the problem. The clue was that node's socket limit was 5, and I was getting 6 at a time. 6 is the limit in Chrome, which is what I was using to test the server.
我对其他答案投了赞成票,因为它们帮助我诊断了问题。线索是节点的套接字限制是 5,而我一次得到 6。6 是 Chrome 中的限制,这是我用来测试服务器的。
回答by josh3736
There are no TCP connection limits imposed by Node itself. (The whole point is that it's highly concurrent and can handle thousands of simultaneous connections.) Your OS maylimit TCP connections.
Node 本身没有强加 TCP 连接限制。(重点是它是高度并发的,可以处理数千个同时连接。)您的操作系统可能会限制 TCP 连接。
It's more likely that you're either hitting some kind of limitation of your backend server, or you're hitting the builtin HTTP library's connection limit, but it's hard to say without more details about that server or your Node implementation.
您更有可能遇到后端服务器的某种限制,或者遇到内置 HTTP 库的连接限制,但如果没有有关该服务器或 Node 实现的更多详细信息,就很难说。
Node's built-in HTTP library(and obviously any libraries built on top of it, which are most) maintains a connection pool (via the Agentclass) so that it can utilize HTTP keep-alives. This helps increase performance when you're running many requests to the same server: rather than opening a TCP connection, making a HTTP request, getting a response, closing the TCP connection, and repeating; new requests can be issued on reused TCP connections.
Node 的内置HTTP 库(显然任何建立在它之上的库,这是大多数)维护一个连接池(通过Agent类),以便它可以利用 HTTP keep-alives。当您对同一服务器运行许多请求时,这有助于提高性能:而不是打开 TCP 连接,发出 HTTP 请求,获得响应,关闭 TCP 连接,然后重复;可以在重用的 TCP 连接上发出新请求。
In node 0.10 and earlier, the HTTP Agent will only open 5 simultaneous connections to a single host by default. You can change this easily: (assuming you've required the HTTP module as http)
在节点 0.10 及更早版本中,默认情况下 HTTP 代理将只打开 5 个与单个主机的同时连接。您可以轻松更改:(假设您已将requireHTTP 模块设置为http)
http.globalAgent.maxSockets = 20; // or whatever
node 0.12sets the default maxSocketsto Infinity.
节点0.12将默认值设置maxSockets为Infinity.
You may want to keep some kind of connection limit in place. You don't want to completely overwhelm your backend server with hundreds of HTTP requests under a second – performance will most likely be worse than if you just let the Agent's connection pool do its thing, throttling requests so as to not overload your server. Your best bet will be to run some experiments to see what the optimal number of concurrent requests is in your situation.
您可能希望保留某种连接限制。您不想在一秒钟内用数百个 HTTP 请求完全淹没后端服务器 - 性能很可能比让代理的连接池做它的事情更糟,限制请求以免使您的服务器过载。最好的办法是运行一些实验,看看在您的情况下并发请求的最佳数量是多少。
However, if you really don't want connection pooling, you can simply bypass the pool entirely – sent agentto falsein the request options:
然而,如果你真的不想要连接池,你可以简单地完全绕过池——在请求选项中发送agent到false:
http.get({host:'localhost', port:80, path:'/', agent:false}, callback);
In this case, there will be absolutely no limit on concurrent HTTP requests.
在这种情况下,并发 HTTP 请求绝对没有限制。
回答by Michelle Tilley
How are you getting data from the central server? "Node does not limit connections" is not entirely accurate when making HTTP requests with the httpmodule. Client requests made in this way use the http.globalAgentinstance of http.Agent, and each http.Agenthas a setting called maxSocketswhich determines how many sockets the agent can have open to any given host; this defaults to 5.
您如何从中央服务器获取数据?使用http模块发出 HTTP 请求时,“节点不限制连接”并不完全准确。以这种方式发出的客户端请求使用 的http.globalAgent实例http.Agent,并且每个http.Agent都有一个调用设置maxSockets,用于确定代理可以向任何给定主机打开多少个套接字;这默认为 5。
So, if you're using http.requestor http.get(or a library that relies on those methods) to get data from your central server, you might try changing the value of http.globalAgent.maxSockets(or modify that setting on whatever instance of http.Agentyou're using).
因此,如果您正在使用http.request或http.get(或依赖于这些方法的库)从中央服务器获取数据,您可以尝试更改的值http.globalAgent.maxSockets(或在http.Agent您使用的任何实例上修改该设置)。
See:
看:
回答by Sharath Holla
I have seen the same problem in my server. It was only processing 4 requests. As explained already from 0.12 maxsockets defaults to infinity. That easily overwhelms the sever. Limiting the requests to say 10 by
我在我的服务器中看到了同样的问题。它只处理 4 个请求。正如已经从 0.12 开始解释的那样,maxsockets 默认为无穷大。这很容易压倒服务器。将请求限制为 10 个
http.globalAgent.maxSockets = 20;
solved my problem.
解决了我的问题。
回答by disjunction
Are you sure it just returns the results to the client? Node processes everything in one thread. So if you do some fancy response parsing or anything else which doesn't yield, then it would block all your requests.
您确定它只是将结果返回给客户端吗?节点在一个线程中处理所有内容。因此,如果您进行一些花哨的响应解析或其他任何不会产生的内容,那么它会阻止您的所有请求。

