Javascript Node.js:http.Server、http.Agent、sockets和http.request之间的关系

Javascript Node.js:http.Server、http.Agent、sockets和http.request之间的关系,javascript,node.js,http,Javascript,Node.js,Http,根据: Node.js为每台服务器维护多个连接以发出HTTP请求。此功能允许透明地发出请求 文档进一步指定默认情况下,节点依赖http.globalAgent发出请求,但您可以通过创建新的http.agent来使用自己的代理。代理用于为http请求“池套接字” 我对这一切的解释是,每次执行http.createServer,默认情况下,您都会得到几个套接字(可能这就是所谓的“连接”)来发出http请求,这些套接字由http.globalAgent汇集/管理 我不清楚的是,当您创建自己的http.

根据:

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

文档进一步指定默认情况下,节点依赖http.globalAgent发出请求,但您可以通过创建新的http.agent来使用自己的代理。代理用于为http请求“池套接字”

我对这一切的解释是,每次执行
http.createServer
,默认情况下,您都会得到几个套接字(可能这就是所谓的“连接”)来发出http请求,这些套接字由
http.globalAgent
汇集/管理

我不清楚的是,当您创建自己的
http.Agent
时会发生什么。
代理是否只是“接管”以前由http.globalAgent管理的套接字?或者您必须通过
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');

请求将从哪个服务器发出?
http.Agent
在这里起作用了吗?

即使是我也对它感到困惑,但最近我找到了答案

代理和全球代理

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

插座

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

创建新代理时,它应管理从其发出的请求的连接。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);
在这段代码中,创建了两台服务器,它们分别在3000和5000监听。这些服务应满足客户的要求。这些与您提出的请求无关。您可以在不创建服务器的情况下发出get请求。您发出的所有请求都由代理处理,因此get方法

http.get('/someurl');
实际上使用了HttpAgent

进一步内容如下:

  • HTTP
    Agent
    为什么我们需要
    代理

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

    代理做什么?

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


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

    如果使用启用了
    keepAlive
    的代理,则最好在不再使用时显式关闭
    agent
    。否则,套接字可能会在服务器终止它们之前长时间处于打开状态。未使用的套接字会消耗操作系统资源


    HTTP
    globalAgent
    http.request()
    http.get()
    方法用于从Node.js服务器或Node.js客户端应用程序向其他服务器发出http请求。为了发出这些请求,默认情况下使用
    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);
    
    如果未使用
    新http.agent()
    指定自定义代理,或者未指定
    {agent