news 2026/8/2 11:30:52

在 Node.js 中使用 HTTP Agent 实现 keep-alive

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Node.js 中使用 HTTP Agent 实现 keep-alive

不带 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 -> 10000

keep-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 官方文档

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/2 11:30:37

从FAQ到问题解决地图:构建高价值知识库的实战方法论

1. 从“常见问题”到“问题解决地图”:一个被低估的认知工具“常见问题”这四个字,在任何一个产品、服务或项目的文档里,几乎都是标配。我们太熟悉它了,以至于常常把它当成一个不得不填的“填空题”,里面塞满了“如何注…

作者头像 李华
网站建设 2026/8/2 11:28:52

Germinal AI:表位靶向抗体设计的生成式人工智能流程详解

1. 项目概述:从“大海捞针”到“精准制导”的抗体设计革命 在抗体药物研发和基础免疫学研究领域,我们长期面临一个核心痛点:如何高效、精准地获得能够特异性结合目标蛋白上某一特定区域(即“表位”)的抗体?…

作者头像 李华
网站建设 2026/8/2 11:24:01

终极指南:3步轻松解密网易云音乐NCM格式,实现音乐自由播放

终极指南:3步轻松解密网易云音乐NCM格式,实现音乐自由播放 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM加密文件无法在其他设备播放而烦恼吗?今天我将为你介绍一款简…

作者头像 李华
网站建设 2026/8/2 11:23:30

如何轻松下载在线视频:N_m3u8DL-CLI-SimpleG完整使用指南

如何轻松下载在线视频:N_m3u8DL-CLI-SimpleG完整使用指南 【免费下载链接】N_m3u8DL-CLI-SimpleG N_m3u8DL-CLIs simple GUI 项目地址: https://gitcode.com/gh_mirrors/nm3/N_m3u8DL-CLI-SimpleG 还在为复杂的命令行视频下载工具而烦恼吗?N_m3u8…

作者头像 李华