当前位置: 首页 > news >正文

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

http://www.jsqmd.com/news/1313208/

相关文章:

  • 信号与系统核心概念深度解析:从傅里叶变换到采样定理的60个关键考点
  • 开发者怎样用 MainBody 从 Bug 描述走到测试通过?
  • 基于STM32与Proteus的FFT谐波失真测量系统仿真实现
  • React 的 state 和 setState 有么区别?:深入理解组件状态与更新机制的核心差异
  • Palworld存档编辑终极指南:3种方法轻松修改游戏数据
  • `import random` 是 Python 中导入标准库模块 `random` 的语句,用于生成伪随机数、执行随机选择(如随机抽样、打乱顺序等)
  • 3分钟搞定Windows和Office激活:智能KMS激活脚本完全指南
  • 如何3步解锁Wand游戏修改器的完整功能体验
  • 腾讯云 ADP 智能体上线前,为什么先做一次 AgentOps 审计比急着调参数更重要
  • 2026日照宠物店推荐品种造假套路揭秘选这5家不吃亏 - 莘州文化
  • GEO优化工具怎么选?如何科学评估AI搜索的推荐质量?
  • 电商运营怎样用 MainBody 从商品实拍生成一组可用素材?
  • 售楼处电子沙盘定制开发多少钱?
  • 工业边缘计算实战:基于Node-RED与Modbus TCP的数据采集与可视化
  • 技术深度解析:LayerDivider 智能图层分离架构揭秘
  • 工业物联网数据采集:RS485转以太网协议转换网关实战指南
  • React触摸事件全解析:掌握移动端交互开发的核心秘籍
  • 高性能电脑电源选购指南:从瞬时功耗到全汉Hydro G Pro 1200W实战解析
  • VibeCoding:通过术语准确性提升AI编程协作效率
  • 【AI数据看板黄金架构标准】:基于127家客户实践提炼的4层模型(接入层/语义层/智能层/交互层)
  • Grove Arduino套件入门指南:模块化硬件开发与传感器应用实战
  • 合肥共达职业技术学院2026年1+3预科复读班:升学路径全解读 - 小张zc
  • 零成本获取全球金融数据:AKShare如何让你的投资分析更简单
  • Wi-Fi无缝漫游核心技术:802.11k/v/r协议原理与实战部署指南
  • 影刀邮件自动化案例分析,证书备考别只学发送
  • AI药物设计新范式:基于概率扩散模型与等变网络的靶向分子生成
  • 在线渗透盒子:安全测试工具Web化平台的架构设计与实战
  • AI 是搭子不是替代者:我用大模型工具(cursor,trae)编程的一年经验总结
  • 终极音乐解锁工具:3分钟让你的加密音乐重获自由
  • STM32 UART通信实战:从轮询到DMA的指令解析框架构建