高并发Axios调用出现ECONNREFUSED/ETIMEDOUT错误的排查与解决
错误原因分析
1. connect ECONNREFUSED ::1:8000(本地接口连接被拒)
- 本地服务器并发处理能力不足:
axios.all一次性发起大量请求到本地/record-coi-cex/:symbol接口,超过服务器默认的并发连接上限,导致新连接直接被拒绝。 - 本地接口逻辑阻塞事件循环:
/record-coi-cex/:symbol中MongoDB的未优化异步操作(或同步操作)长时间占用Node.js事件循环,服务器无法及时响应新的请求连接。 - 端口资源堆积:短时间高频请求导致本地8000端口的TIME_WAIT连接堆积,无法建立新的连接。
2. connect ETIMEDOUT(第三方API超时)
- 第三方API触发限流:批量高频请求触发对方的频率限制策略,服务器拒绝或延迟响应,最终导致连接超时。
- 本地请求并发超限:Node.js默认HTTP连接池(默认5个并发)被占满,后续请求排队等待超时;或系统文件描述符不足,无法创建新的网络连接。
- 第三方服务不稳定:对方服务器负载过高或临时故障,无法及时处理请求。
解决方案
针对本地接口连接被拒的处理
- 控制本地请求并发量:放弃
axios.all一次性批量请求,改用并发限制工具(如p-limit)控制同时调用本地接口的数量:const pLimit = require('p-limit'); const limit = pLimit(5); // 同时最多发起5个本地请求 const symbolList = await getLocalSymbolList(); // 获取本地symbol列表 const tasks = symbolList.map(symbol => limit(() => axios.get(`/record-coi-cex/${symbol}`))); await Promise.all(tasks); - 优化本地接口性能:
- 复用MongoDB连接池,避免每次请求创建新连接;
- 给MongoDB查询/更新操作添加索引,提升数据操作效率;
- 确保所有数据库操作都是非阻塞异步模式,避免占用事件循环。
- 调整服务器配置:
- 若使用Express,通过
server.maxConnections提高并发连接上限; - 启用Node.js Cluster模式,利用多核CPU分担请求处理压力。
- 若使用Express,通过
针对第三方API超时的处理
- 限制第三方API请求并发:用
p-limit控制同时请求第三方API的数量,避免触发限流:const apiLimit = pLimit(3); // 根据第三方API限制设置并发数 const fetchOptionsData = symbol => apiLimit(() => axios.get('第三方API地址', { params: { symbol } })); - 添加重试与超时配置:给axios请求添加超时时间和自动重试机制,应对临时网络波动:
const axiosRetry = require('axios-retry'); axiosRetry(axios, { retries: 3, // 最多重试3次 retryDelay: retryCount => retryCount * 1000, // 每次重试间隔递增1秒 retryCondition: error => error.code === 'ETIMEDOUT' || error.code === 'ECONNREFUSED' }); // 单个请求设置10秒超时 await axios.get('第三方API地址', { timeout: 10000 }); - 遵守频率限制:查询第三方API文档明确请求频率规则(如每秒最多5次),添加请求间隔:
// 串行请求加固定间隔 for (const symbol of symbolList) { await fetchOptionsData(symbol); await new Promise(resolve => setTimeout(resolve, 200)); // 每次请求间隔200毫秒 }
内容的提问来源于stack exchange,提问作者Chaser
相关产品推荐
相关产品推荐

