
不带 Keep-Alive 的请求我们都知道浏览器中多个 HTTP 请求是可以通过请求头connection: keep-alive;来复用 TCP 连接的但是在 Node.js 中怎么实现呢比如下面是一段简单的发起请求的代码// server.js const http require(http) http .createServer((req, res) { res.writeHead(200) res.end(Hello World) }) .listen(3000) // client.js const http require(http) function request() { http .request( { host: localhost, port: 3000, pathname: /, }, (res) { let buffer [] res.on(data, (chunk) { buffer.push(chunk) }) res.on(end, () { console.log(buffer.toString()) }) } ) .end() } request() setTimeout(() { request() }, 5000)当我们用 wireshard 抓包分析时我们发现两次请求的 client 端口是不同的并且有两个“三次握手”的过程使用 http.Agent 发送带有 Keep-Alive 的请求现在让我们使用http.Agent来实现keep-alive请求我们只需要加少量的代码// client.js const http require(http) const agent new http.Agent({ keepAlive: true, }) function request() { http .request( { host: localhost, port: 3000, pathname: /, agent }, (res) { let buffer [] res.on(data, (chunk) { buffer.push(chunk) }) res.on(end, () { console.log(buffer.toString()) }) } ) .end() } request() setTimeout(() { request() }, 5000)maxSockets表示每个 host 所能建立的最大 TCP 连接数。其默认值是Infinity。如果我们不指定它的值那每个 HTTP 请求都会建立一个 TCP 连接。const agent new http.Agent({ keepAlive: true, maxSockets: 1, })接下来我们修改一下代码setTimeout(() { request() }, 10000) // 1000 - 10000keep-alive又不生效了并且我们可以看到服务端 5s 左右后发送了一个 FIN 的包。难道有什么参数可以控制keep-alive的超时时间么确实也就是keepAliveTimeout我们把它设置为 10s:const http require(http) const server http .createServer((req, res) { res.writeHead(200) res.end(Hello World) }) .listen(3000) server.keepAliveTimeout 10000现在keep-alive又可以工作了。总结首先 Node.js 的 http 库提供三个主要的函数 http.request, http.get, http.createServer。前两个函数主要是为了创建 http 客户端向其它服务器发送请求http.get 只是 http.request 的发送 get 请求的便捷方式而 http.createServer 是为了创建 Node 服务比如 Koa 服务框架就是基于 http.createServer 封装的。而 http.Agent 主要是为 http.request, http.get 提供代理服务的用于管理 http 连接的创建销毁及复用工作。http.request, http.get 默认使用 http.globalAgent 作为代理每次请求都是“建立连接-数据传输-销毁连接”的过程如果我们想让多个请求复用同一个 connection则需要重新定义 agent 去覆盖默认的 http.globalAgent下面我们看一下新建一个agent的需要哪些主要参数keepAlive{Boolean} 是否开启 keepAlive多个请求公用一个 socket connection默认是 false。 maxSockets{Number} 每台主机允许的socket的最大值默认值为Infinity。 maxFreeSockets{Number} 处于连接池空闲状态的最大连接数 仅当开启 keepAlive 才有效。 let http require(http); const keepAliveAgent new http.Agent({ keepAlive: true, maxScokets: 1000, maxFreeSockets: 50 }) http.get({ hostname: localhost, port: 80, path: /, agent: keepAliveAgent }, (res) { // Do stuff with response });只有向相同的 host 和 port 发送请求才能公用同一个 keepAlive 的 socket 连接如果开启 keepAlive 同一时间内多个请求会被放在队列里等待如果当前队列为空该 socket 处于空闲状态但是不会被销毁等待下一次请求的到来。使用 keepAlive 代理有效的减少了建立/销毁连接的开销开发者可以对连接池进行动态管理。大体差不多就是这个意思详细可以看Node.js 官方文档