admin 管理员组文章数量: 1184232
Per the docs:
Node.js maintains several connections per server to make HTTP requests. This function allows one to transparently issue requests.
The docs further specify that Node relies on http.globalAgent to make requests by default, but that you can use your own agent by creating a new http.Agent. Agents are used to "pool sockets" for http requests.
My interpretation of all this is that each time you do a http.createServer, by default you get several sockets (presumably that is what is meant by "connections") to make http requests and these sockets are pooled / managed by http.globalAgent.
What isn't clear to me is what happens when you create your own http.Agent. Does the Agent just "take over" the sockets that were previously being managed by http.globalAgent? Or do you have to create a new socket for your new Agent via agent.createConnection?
On a related note, if I were to start up two servers in the same node process and subsequently make an http request, e.g.
const server1 = http.createServer(function(req, res) {
res.end('Hello from server1');
}).listen(3000);
const server2 = http.createServer(function(req, res) {
res.end('Hello from server2');
}).listen(5000);
http.get('/someurl');
from which server would the request be made? Does http.Agent come into play here?
Per the docs:
Node.js maintains several connections per server to make HTTP requests. This function allows one to transparently issue requests.
The docs further specify that Node relies on http.globalAgent to make requests by default, but that you can use your own agent by creating a new http.Agent. Agents are used to "pool sockets" for http requests.
My interpretation of all this is that each time you do a http.createServer, by default you get several sockets (presumably that is what is meant by "connections") to make http requests and these sockets are pooled / managed by http.globalAgent.
What isn't clear to me is what happens when you create your own http.Agent. Does the Agent just "take over" the sockets that were previously being managed by http.globalAgent? Or do you have to create a new socket for your new Agent via agent.createConnection?
On a related note, if I were to start up two servers in the same node process and subsequently make an http request, e.g.
const server1 = http.createServer(function(req, res) {
res.end('Hello from server1');
}).listen(3000);
const server2 = http.createServer(function(req, res) {
res.end('Hello from server2');
}).listen(5000);
http.get('/someurl');
from which server would the request be made? Does http.Agent come into play here?
2 Answers
Reset to default 24HTTP Agent
Why do we need the Agent?
The process of establishing a connection from one host to another involves multiple packet exchanges between two endpoints, this can be quite time consuming, especially for multiple small http requests. The Agent helps achieve a much higher data throughput by keeping the connections open and by reusing them to handle multiple requests from the same host.
What does the Agent do?
The Agent manages connection persistence for HTTP clients. It maintains a queue of pending requests for a given host and port, reusing a single socket connection for each until the queue is empty. After that, the socket is destroyed, if the keepAlive is set to false. If the keepAlive is set to true, the socket is put into a pool where it is kept to be used again for requests to the same host and port. However, servers may still close idle connections.
Socket Management
When a connection is closed by the client or the server, it is removed from the pool. Any unused sockets in the pool will be unrefed so as not to keep the Node.js process running when there are no outstanding requests.
If using an agent with keepAlive enabled, then it is best to explicitly shut down the agent when it will no longer be used. Otherwise, sockets may hang open for quite a long time before the server terminates them. Unused sockets consume OS resources.
HTTP globalAgent
The http.request() or http.get() method is used to make http requests to other servers from your Node.js server or your Node.js client app. For making these requests, the http.globalAgent is used by default.
http.globalAgent is a singleton object. In the source code of Node.js, the http.globalAgent is created using new http.Agent() with default options.
Each agent object has its own array of sockets. So, when you create a custom agent using http.Agent, it will have a different set of sockets from http.globalAgent. The unused sockets of the globalAgent will be destroyed automatically after the timeout.
Multiple Servers in a Process
As specified in question, if you start the two servers in the same node process and make the http request after the server code, the request will go through the same globalAgent. The server 1 and 2 are irrelevant to the http.get() request made in your code. The http.get() will be executed outside of the server code. However, you can also make an http request to another server from your server code as shown below:
const server1 = http.createServer(function(req, res) {
http.get('/someurl');
res.end('The request has been made from server1');
}).listen(3000);
If you don't specify your custom agent using the new http.Agent() or if you don't specify {agent : false} in your request options, the http.globalAgent will be used for the code above too.
agent.createConnection()
The function agent.createConnection() is used when you want to avoid creating a custom agent as well as http.globalAgent. This function directly gives you a socket for making your http request.
Hope this clears all your doubts about the HTTP Agent!
Even I was confused with the same, but recently I found the answers.
Agents and globalAgent
Agents are the source used by the Node to make requests to a new server. Here you can find that the Agent makes a request call. The Agent needs to have the host, port and some other custom headers (KeepAlive etc) to send a request. If no agent is specified then Node uses globalAgent by default. From here we can analyze that most of the headers are set by default. Both of these are helpful in making a request, so if you have a service running at 127.0.0.1:8080 you can make a request using these.
Sockets
As you mentioned, Sockets are the connections and using these connections the requests are made to the given server. These sockets are managed by the OS(say Linux), it creates a new socket handler for each socket. The list of sockets for a particular domain is however maintained in the Agent/globalAgent. We can set the maxSockets, maxFreeSockets etc. These help us in keeping a check on the usage of OS resources.
When a new agent is created, it shall manage the connections of the requests that are made from it. agent.createConnection creates a TCP socket. Here it is mentioned that it returns net.socket, so you can listen on this socket for any streams using events.
const server1 = http.createServer(function(req, res) {
res.end('Hello from server1');
}).listen(3000);
const server2 = http.createServer(function(req, res) {
res.end('Hello from server2');
}).listen(5000);
In this code, there are 2 servers created and they are listening at 3000 and 5000. These shall serve the requests made by clients. These have nothing to do with the request that you make. You can make a get request without creating a server. All the requests you make are handled by the Agent, so the get method in the line
http.get('/someurl');
actually uses the HttpAgent.
Further Reads:
- https://translate.google.com/translate?sl=auto&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fwyicwx.github.io%2F2014%2F03%2F12%2F%25E8%25B0%2588%25E8%25B0%2588nodejs%25E4%25B8%25ADhttpagent%2F&edit-text=&act=url
- http://www.hacksparrow.com/tcp-socket-programming-in-node-js.html
本文标签:
版权声明:本文标题:javascript - Node.js: Relationship among http.Server, http.Agent, sockets, and http.request - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1738146476a1932455.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论