You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Function中Node.js定时函数间歇性DNS解析失败求助

Azure消费计划Node.js定时函数间歇性DNS解析失败(EAI_AGAIN)问题排查与解决建议

问题背景

运行在Azure Linux环境、消费计划下的Node.js v18定时函数,每30分钟执行一次,出现间歇性DNS解析异常:正常运行数天后,会持续12-24小时无法解析api.hubapi.com,之后自动恢复。报错发生在@hubspot/api-client调用HubSpot API时,具体错误日志:

Exception: request to https://api.hubapi.com/crm/v3/objects/products?limit=100&after=2663219990&properties=hs_lastmodifieddate%2Chs_sku%2Chs_images&archived=false failed, reason: getaddrinfo EAI_AGAIN api.hubapi.com

已尝试的排查措施:

  • 更新@hubspot/api-client至最新版本,排除库本身问题
  • 将Function App出站DNS改为Cloudflare(1.1.1.1)和Quad9(9.9.9.9),替换默认Azure DNS

该函数在本地及GCP环境运行正常。

针对性解决建议

1. 针对消费计划实例特性添加DNS解析重试逻辑

Azure消费计划的实例会频繁启停、回收,可能导致DNS缓存异常或解析请求临时被限流。建议在代码中针对EAI_AGAIN错误添加重试机制:

  • 使用p-retry等重试库,配置针对DNS解析错误的重试策略,比如间隔10秒、最多重试5次
  • 或者在@hubspot/api-client的配置中开启内置重试(如果支持),明确指定包含EAI_AGAIN的错误码

示例代码片段:

const pRetry = require('p-retry');
const { Client } = require('@hubspot/api-client');

const hubspotClient = new Client({ accessToken: 'YOUR_TOKEN' });

async function fetchProducts() {
  return pRetry(async () => {
    const response = await hubspotClient.crm.products.getPage(100, '2663219990', ['hs_lastmodifieddate', 'hs_sku', 'hs_images'], false);
    return response;
  }, {
    retries: 5,
    factor: 2,
    minTimeout: 10000,
    onFailedAttempt: (error) => {
      console.log(`重试第 ${error.attemptNumber} 次,原因: ${error.message}`);
    },
    shouldRetry: (error) => {
      // 仅针对DNS解析失败的EAI_AGAIN错误重试
      return error.message.includes('EAI_AGAIN');
    }
  });
}

2. 手动解析域名绕过系统DNS缓存

在调用API前,手动用Node.js dns模块解析api.hubapi.com的IP,直接使用IP发起请求(需处理SNI,指定主机头):

const dns = require('dns').promises;
const https = require('https');

async function fetchWithManualDns() {
  const ips = await dns.resolve4('api.hubapi.com');
  const ip = ips[0]; // 取第一个解析到的IP

  const options = {
    hostname: ip,
    port: 443,
    path: '/crm/v3/objects/products?limit=100&after=2663219990&properties=hs_lastmodifieddate%2Chs_sku%2Chs_images&archived=false',
    method: 'GET',
    headers: {
      'Host': 'api.hubapi.com', // 必须指定主机头以支持SNI
      'Authorization': 'Bearer YOUR_TOKEN'
    }
  };

  return new Promise((resolve, reject) => {
    const req = https.request(options, (res) => {
      let data = '';
      res.on('data', (chunk) => data += chunk);
      res.on('end', () => resolve(JSON.parse(data)));
    });
    req.on('error', reject);
    req.end();
  });
}

3. 检查Azure消费计划的网络限制

  • 确认Function App所在区域的Azure服务健康状态,排查是否存在区域性DNS服务波动
  • 配置WEBSITE_DNS_REFRESH_INTERVAL环境变量(单位秒),强制缩短DNS缓存刷新周期,比如设置为300(5分钟)
  • 考虑临时切换到弹性计划测试,排除消费计划特有的网络隔离或资源限制问题

4. 验证自定义DNS配置有效性

虽然已配置自定义DNS,但需确认配置是否生效:

  • 在函数代码中添加DNS解析测试,调用dns.resolve('api.hubapi.com')并打印解析结果
  • 检查Function App的网络配置,确保自定义DNS服务器地址未被防火墙或网络规则拦截

内容的提问来源于stack exchange,提问作者wooters

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:20:59