Node.js使用Axios调用外部接口偶发ETIMEDOUT连接超时问题咨询
Node.js环境axios偶发
connect ETIMEDOUT 12.123.12.123:443错误排查 问题现象
Node.js服务中使用axios调用外部HTTPS接口,多数请求可正常返回,偶发抛出如下连接超时错误,当前axios客户端仅配置了baseUrl与Authorization请求头,未设置timeout参数:
AxiosError: connect ETIMEDOUT 12.123.12.123:443 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16) { port: 443, address: '12.123.12.123', syscall: 'connect', code: 'ETIMEDOUT', errno: -60, config: { transitional: { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }, adapter: [Function: httpAdapter], transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, env: { FormData: [Function] }, validateStatus: [Function: validateStatus], headers: { Accept: 'application/json, text/plain, */*', Authorization: 'Basic <AUTH_KEY>', 'User-Agent': 'axios/0.27.2' }, baseURL: 'https://api.staffology.co.uk', method: 'get', url: '/employers', data: undefined } }
触发原因
- TCP握手阶段链路异常:该错误发生在TCP三次握手环节,代表客户端发出的连接请求没有得到服务端响应,和接口业务逻辑处理慢导致的响应超时不是一类问题。公网调用时跨运营商路由波动、临时链路丢包是偶发该错误的最常见诱因。
- 目标服务端限流/过载:当被调用的API服务处于请求高峰、连接数达到上限时,会直接丢弃超出承载能力的握手包,不会返回明确的拒绝响应,客户端会持续等待直到触发操作系统默认的60秒TCP连接超时(对应报错里的
errno: -60)。 - 本地端口资源耗尽:如果服务请求量较高,且未开启TCP连接复用,短时间内会产生大量短连接,临时端口进入TIME_WAIT状态后需要等待2MSL时长才能释放,新连接无可用端口时也会触发连接超时。
- 出口网络策略拦截:本地服务器防火墙、云服务商安全组、企业内网网关如果存在规则异常、SNAT端口配额不足的情况,会随机拦截出站连接请求,表现为无规律的偶发超时。
注意:当前配置中
timeout: 0代表axios层未设置请求总时长上限,该参数只能控制从请求发起到收到完整响应的总耗时,无法干预TCP握手阶段的超时逻辑,对解决当前报错没有直接作用。
修复方案
- 针对幂等请求添加重试逻辑:偶发网络抖动类错误通过重试即可覆盖绝大多数场景,可直接使用axios-retry插件,配置针对网络层错误、5xx服务端错误做3次以内的指数退避重试,避免瞬时重试加重服务端负载。基础配置示例:
const axios = require('axios'); const axiosRetry = require('axios-retry'); // 初始化客户端时补全合理的总超时配置 const apiClient = axios.create({ baseURL: 'https://api.staffology.co.uk', headers: { Authorization: 'Basic <AUTH_KEY>' }, timeout: 10000 // 单请求总超时设为10秒,避免异常请求挂死 }); // 配置重试规则 axiosRetry(apiClient, { retries: 3, retryDelay: axiosRetry.exponentialDelay, retryCondition: (err) => { return axiosRetry.isNetworkError(err) || axiosRetry.isRetryableError(err); } });
- 开启TCP连接复用:初始化axios时传入开启keepAlive的http/https agent,复用已建立的TCP连接,减少重复握手开销,同时降低短连接导致的端口占用问题:
const http = require('http'); const https = require('https'); const apiClient = axios.create({ // 其余配置保持不变 httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }) });
- 排查本地出口资源:如果服务部署在云服务器上,监控TCP连接状态,若TIME_WAIT连接数过高,可调整内核参数扩大临时端口范围、开启端口复用;若在内网环境部署,联系网络管理员确认防火墙是否存在针对目标IP的偶发拦截规则。
- 若调整后报错频率仍较高,联系目标API服务方确认账号限流阈值、接入IP是否存在被拦截的情况。
内容的提问来源于stack exchange,提问作者rb27
相关产品推荐
相关产品推荐

