http.Agent 类


Agent 负责管理 HTTP 客户端连接的持久性和重用。 它维护一个给定主机和端口的待处理请求队列,为每个请求重用单个套接字连接,直到队列为空,此时套接字要么被销毁,要么放入池中,在那里它会被再次用于请求到相同的主机和端口。 是销毁还是池化取决于 keepAlive 选项

池化的连接会为其启用 TCP Keep-Alive,但服务器可能仍会关闭空闲连接,在这种情况下,它们将从池中删除,并在为该主机和端口发出新的 HTTP 请求时建立新连接。 服务器也可能拒绝允许通过同一个连接的多个请求,在这种情况下,必须为每个请求重新建立连接,并且不能池化。 Agent 仍将向该服务器发出请求,但每个请求都将通过新连接发生。

当客户端或服务器关闭连接时,它会从池中删除。 池中任何未使用的套接字都将被取消引用,以免在没有未完成请求时保持 Node.js 进程运行。 (见 socket.unref())。

一个很好的做法是,当不再使用时则 destroy() Agent 实例,因为未使用的套接字会消耗操作系统资源。

当套接字触发 'close' 事件或 'agentRemove' 事件时,则套接字将从代理中删除。 当打算让 HTTP 请求长时间打开而不将其保留在代理中时,可以执行类似以下的操作:

http.get(options, (res) => {
  // 做些事情
}).on('socket', (socket) => {
  socket.emit('agentRemove');
});

代理也可用于单个请求。 通过提供 {agent: false} 作为 http.get()http.request() 函数的选项,则单次使用的具有默认选项的 Agent 将用于客户端连接。

agent:false:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // 仅为这个请求创建新代理
}, (res) => {
  // 使用响应做些事情
});

An Agent is responsible for managing connection persistence and reuse 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, at which time the socket is either destroyed or put into a pool where it is kept to be used again for requests to the same host and port. Whether it is destroyed or pooled depends on the keepAlive option.

Pooled connections have TCP Keep-Alive enabled for them, but servers may still close idle connections, in which case they will be removed from the pool and a new connection will be made when a new HTTP request is made for that host and port. Servers may also refuse to allow multiple requests over the same connection, in which case the connection will have to be remade for every request and cannot be pooled. The Agent will still make the requests to that server, but each one will occur over a new connection.

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. (see socket.unref()).

It is good practice, to destroy() an Agent instance when it is no longer in use, because unused sockets consume OS resources.

Sockets are removed from an agent when the socket emits either a 'close' event or an 'agentRemove' event. When intending to keep one HTTP request open for a long time without keeping it in the agent, something like the following may be done:

http.get(options, (res) => {
  // Do stuff
}).on('socket', (socket) => {
  socket.emit('agentRemove');
});

An agent may also be used for an individual request. By providing {agent: false} as an option to the http.get() or http.request() functions, a one-time use Agent with default options will be used for the client connection.

agent:false:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // Create a new agent just for this one request
}, (res) => {
  // Do stuff with response
});