Node.js中如何管理大量HTTP GET请求?求推荐适配库
处理批量HTTP GET请求的实用工具推荐
我之前处理过类似的批量请求场景,刚好能给你分享几个常用的工具,它们完美平衡了队列控制和连接复用,不会让请求一下子打垮目标服务器:
1. p-limit - 轻量并发控制器
这是我最常用的工具之一,它的核心就是限制同时运行的Promise数量,非常适合批量处理HTTP请求。你可以把每个GET请求包装成Promise,然后用p-limit控制并发数,同时搭配HTTP客户端(比如axios、node-fetch)的内置连接池,实现连接复用+并发队列的双重控制。
示例代码:
const pLimit = require('p-limit'); const axios = require('axios'); // 限制同时发起5个请求 const limit = pLimit(5); const ids = [...Array(1000).keys()].map(i => i + 100); // 生成100到1099的ID // 把每个请求包装成被limit控制的函数 const requestTasks = ids.map(id => limit(() => axios.get(`http://foo.com/bar?id=${id}`) .then(response => { // 处理响应 return { id, data: response.data }; }) .catch(err => { // 处理错误 console.error(`请求ID ${id}失败:`, err.message); return { id, error: err.message }; }) )); // 等待所有请求完成 Promise.all(requestTasks).then(results => { // 处理最终结果 console.log('所有请求完成', results.length); });
2. bottleneck - 功能全面的速率限制器
如果你的场景需要更精细的控制(比如限制每秒请求数、设置请求间隔),bottleneck会是更好的选择。它不仅能控制并发数,还能设置请求速率阈值,支持队列优先级,甚至可以和连接池无缝配合。
示例代码:
const Bottleneck = require('bottleneck'); const axios = require('axios'); // 配置:最多同时3个请求,每200ms发起一个请求(即每秒5个) const limiter = new Bottleneck({ maxConcurrent: 3, minTime: 200 }); const ids = [...Array(1000).keys()].map(i => i + 100); // 用limiter包装请求函数 const limitedRequest = limiter.wrap(id => axios.get(`http://foo.com/bar?id=${id}`) .then(res => ({ id, data: res.data })) .catch(err => ({ id, error: err.message })) ); // 批量执行请求 Promise.all(ids.map(limitedRequest)).then(results => { console.log('批量请求完成'); });
3. 结合axios内置连接池 + 自定义队列
其实Node.js的http模块本身就有Agent连接池(axios默认使用它),你可以调整连接池的参数,再配合简单的队列逻辑,也能实现需求。比如修改axios的httpAgent配置,增加最大socket数量,再用p-limit控制并发数,这样既复用连接,又控制请求量:
const axios = require('axios'); const http = require('http'); const pLimit = require('p-limit'); // 配置连接池:最多10个复用的socket连接 const agent = new http.Agent({ keepAlive: true, maxSockets: 10 }); const customAxios = axios.create({ httpAgent: agent }); const limit = pLimit(10); // 并发数和连接池数量对应 const ids = [...Array(1000).keys()].map(i => i + 100); const tasks = ids.map(id => limit(() => customAxios.get(`http://foo.com/bar?id=${id}`) .then(res => ({ id, data: res.data })) )); Promise.all(tasks).then(console.log);
这些工具的核心思路都是用队列控制并发请求数,用连接池复用TCP连接,刚好符合你说的“介于队列与连接池之间”的需求。根据你的场景复杂度选择就行,p-limit适合简单场景,bottleneck适合需要精细速率控制的场景。
内容的提问来源于stack exchange,提问作者gaelicyoda
相关产品推荐
相关产品推荐

