Node.js端HTTPDNS+阿里云OSS SDK最佳实践

本文档介绍在Node.js应用中使用阿里云OSS SDK接入HTTPDNS的方案。

1. 背景说明

阿里云对象存储OSS(Object Storage Service)是一款通用的云存储服务,可让开发者在各类应用中便捷地存储和访问用户头像、图片、音视频等文件。在Node.js端,可以通过集成OSS Node.js SDK来完成。

为了提升文件传输的稳定性和速度,可以将HTTPDNS SDKOSS Node.js SDK进行结合,对OSS域名进行解析。这可以有效实现域名防劫持和DNS解析加速,从而优化应用访问OSS的网络体验。

2. 接入步骤

Node.js上,将HTTPDNSOSS SDK进行集成,整个接入过程分为以下三个核心步骤:

  1. 安装和初始化HTTPDNS SDK

  2. 创建集成HTTPDNS的自定义Agent

  3. 使用自定义Agent初始化OSS客户端

2.1 安装依赖

首先安装必要的依赖包:

Node.js SDK及接入示例下载:httpdns-nodejs-sdk.zip

npm install ali-oss

版本要求:

  • ali-oss: >= 4.0.0

  • Node.js: >= 12.0.0

  • httpdns-nodejs-sdk: >= 1.0.0

2.2 初始化HTTPDNS SDK

在应用启动时初始化HTTPDNS SDK:

const { createClient } = require('httpdns-nodejs-sdk');

// 初始化HTTPDNS客户端
const httpdnsClient = createClient({
  accountId: 'your-account-id',
  secretKey: 'your-secret-key', // 可选,用于鉴权解析
});

2.3 创建集成HTTPDNS的自定义Agent

创建一个自定义的HTTPS Agent,集成HTTPDNS解析能力:

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

/**
 * 创建自定义DNS lookup函数
 */
function createHTTPDNSLookup(httpdnsClient) {
  return (hostname, options, callback) => {
    // 标准化参数
    if (typeof options === 'function') {
      callback = options;
      options = {};
    }
  
    // 确保callback存在
    if (typeof callback !== 'function') {
      throw new Error('callback must be a function');
    }
  
    // 使用 HTTPDNS 解析域名
    const result = this.httpdnsClient.getHttpDnsResultForHostSyncNonBlocking(hostname);
  
    if (result && result.success) {
      const hasIPv4 = result.ipv4 && result.ipv4.length > 0;
      const hasIPv6 = result.ipv6 && result.ipv6.length > 0;
  
      if (hasIPv4 || hasIPv6) {
        if (options && options.all) {
          // 返回所有IP
          const addresses = [
            ...(hasIPv4 ? result.ipv4.map(ip => ({ address: ip, family: 4 })) : []),
            ...(hasIPv6 ? result.ipv6.map(ip => ({ address: ip, family: 6 })) : [])
          ];
          console.log(`[DNS Lookup] HTTPDNS 解析成功: ${hostname} -> 返回所有IP (${addresses.length}个)`);
          callback(null, addresses);
        } else {
          // 优先IPv4,其次IPv6
          if (hasIPv4) {
            console.log(`[DNS Lookup] HTTPDNS 解析成功: ${hostname} -> ${result.ipv4[0]} (IPv4)`);
            callback(null, result.ipv4[0], 4);
          } else {
            console.log(`[DNS Lookup] HTTPDNS 解析成功: ${hostname} -> ${result.ipv6[0]} (IPv6)`);
            callback(null, result.ipv6[0], 6);
          }
        }
        return;
      }
    }
  
    console.log(`[DNS Lookup] HTTPDNS 无可用IP,降级到系统 DNS: ${hostname}`);
    dns.lookup(hostname, options, callback);
  };
}

/**
 * 创建集成HTTPDNS的HTTPS Agent
 */
function createHTTPDNSAgent(httpdnsClient) {
  return new https.Agent({
    lookup: createHTTPDNSLookup(httpdnsClient),
    keepAlive: true,
    maxSockets: 10,
  });
}

2.4 初始化OSS客户端

使用自定义Agent初始化OSS客户端:

const OSS = require('ali-oss');

/**
 * 创建集成HTTPDNS的OSS客户端
 */
function createOSSClient(httpdnsClient, ossConfig) {
  // 创建自定义Agent
  const httpsAgent = createHTTPDNSAgent(httpdnsClient);
  
  // 创建OSS客户端,传入自定义Agent
  const ossClient = new OSS({
    region: ossConfig.region,
    accessKeyId: ossConfig.accessKeyId,
    accessKeySecret: ossConfig.accessKeySecret,
    bucket: ossConfig.bucket,
    httpsAgent: httpsAgent // 核心:传入集成HTTPDNS的Agent
  });

  console.log('OSS客户端创建完成,已集成HTTPDNS');
  return ossClient;
}

// 使用示例
const ossConfig = {
  region: 'oss-cn-hangzhou',
  accessKeyId: 'your-access-key-id',
  accessKeySecret: 'your-access-key-secret',
  bucket: 'your-bucket-name'
};

const ossClient = createOSSClient(httpdnsClient, ossConfig);

3. 总结

通过将HTTPDNSOSS Node.js SDK结合,可以有效防止DNS劫持并加速文件传输,提升访问的稳定性和安全性。实现的核心是为OSS配置一个带有HTTPDNS解析逻辑的自定义https.Agent

关键要点:

  • 初始化顺序: 必须先初始化HTTPDNS,再初始化OSS客户端。

  • 降级处理: HTTPDNS解析失败时降级到系统DNS。

通过遵循本文的最佳实践,可以在Node.js应用中实现高性能、高可用的OSS访问服务。

HTTPDNS Node.js SDK的详细使用方法和API说明,请参考Node.js最佳实践