Node.js:http.Server,http.Agent,套接字和http.request之间的关系

Mar*_*lvy 12 javascript http node.js

根据文档:

Node.js为每个服务器维护多个连接以发出HTTP请求.此功能允许用户透明地发出请求.

文档进一步指定Node http.globalAgent默认依赖于发出请求,但您可以通过创建新代理来使用自己的代理http.Agent.代理用于为http请求"池套接字".

我对这一切的解释是,每次你执行一次操作时http.createServer,默认情况下你会得到几个套接字(可能就是"连接"的含义)来发出http请求,这些套接字是由它们汇集/管理的http.globalAgent.

我不清楚的是,当你创建自己的时候会发生什么http.Agent.是否Agent只是"接管"以前由其管理的套接字http.globalAgent?或者你必须为你的新Agent通道创建一个新的插座agent.createConnection

在相关的说明中,如果我在同一节点进程中启动两个服务器并随后发出http请求,例如

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');
Run Code Online (Sandbox Code Playgroud)

从哪个服务器请求?并http.Agent开始发挥作用吗?

小智 8

甚至我也对此感到困惑,但最近我找到了答案。

代理和全局代理

代理是节点用来向新服务器发出请求的源。在这里您可以发现 Agent 发出请求调用。代理需要有主机、端口和一些其他自定义标头(KeepAlive 等)来发送请求。如果未指定代理,则 Node 默认使用 globalAgent。从这里我们可以分析,大多数标题都是默认设置的。这两者都有助于发出请求,因此如果您的服务在 127.0.0.1:8080 上运行,则可以使用它们发出请求。

插座

正如您所提到的,套接字是连接,使用这些连接向给定服务器发出请求。这些套接字由操作系统(比如 Linux)管理,它为每个套接字创建一个新的套接字处理程序。然而,特定域的套接字列表在 Agent/globalAgent 中维护。我们可以设置maxSocketsmaxFreeSockets等。这些有助于我们检查操作系统资源的使用情况。

当一个新的代理被创建时,它应该管理从它发出的请求的连接。agent.createConnection 创建一个 TCP 套接字。这里提到它返回net.socket,因此您可以使用事件在此套接字上侦听任何流。

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);
Run Code Online (Sandbox Code Playgroud)

在此代码中,创建了 2 个服务器,它们分别在 3000 和 5000 处侦听。它们应为客户端发出的请求提供服务。这些与您提出的请求无关。您可以在不创建服务器的情况下发出 get 请求。您发出的所有请求都由代理处理,因此该行中的 get 方法

http.get('/someurl');
Run Code Online (Sandbox Code Playgroud)

实际上使用了HttpAgent。

进一步阅读:

  1. 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
  2. http://www.hacksparrow.com/tcp-socket-programming-in-node-js.html


Yog*_*ity 6

HTTP Agent

为什么我们需要Agent

建立从一台主机到另一台主机的连接的过程涉及两个端点之间的多个数据包交换,这可能非常耗时,尤其是对于多个小的 http 请求。Agent通过保持连接打开并重用它们来处理来自同一主机的多个请求,这有助于实现更高的数据吞吐量。

代理是做什么的?

Agent用于HTTP客户端管理连接持久。它维护给定主机和端口的待处理请求队列,为每个请求重用单个套接字连接,直到队列为空。之后,如果keepAlive设置为,则套接字将被销毁false。如果keepAlive设置为true,则套接字被放入一个池中,在那里它会被再次用于对同一主机和端口的请求。但是,服务器可能仍会关闭空闲连接。


套接字管理

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

如果使用keepAlive启用的代理,那么最好在agent不再使用时明确关闭。否则,套接字可能会在服务器终止它们之前挂起很长时间。未使用的套接字消耗操作系统资源。


HTTP globalAgent

http.request()http.get()方法用于发出HTTP请求到其他服务器从您的Node.js服务器或Node.js的客户端应用程序。为了发出这些请求,http.globalAgent默认使用 。

http.globalAgent是一个单例对象。在 Node.js 的源代码中,http.globalAgent使用new http.Agent()默认选项创建。

每个agent对象都有自己的套接字数组。因此,当您使用 来创建自定义代理时http.Agent,它将具有一组与 不同的套接字http.globalAgent。未使用的套接字globalAgent将在超时后自动销毁。


一个进程中的多个服务器

如上所述,如果您在同一个节点进程中启动两个服务器并在服务器代码之后发出 http 请求,则请求将通过相同的globalAgent. 服务器 1 和 2 与http.get()您的代码中发出的请求无关。在http.get()将服务器代码之外执行。但是,您也可以从您的服务器代码向另一台服务器发出 http 请求,如下所示:

const server1 = http.createServer(function(req, res) {
  http.get('/someurl');
  res.end('The request has been made from server1');
}).listen(3000);
Run Code Online (Sandbox Code Playgroud)

如果您未使用new http.Agent()或未{agent : false}在请求选项中指定自定义代理,则http.globalAgent也将用于上面的代码。


agent.createConnection()

该功能agent.createConnection()时,要避免创建自定义代理以及使用http.globalAgent。此函数直接为您提供一个用于发出 http 请求的套接字。


希望这能消除您对 HTTP 代理的所有疑虑!