最佳实践建议

HTTPDNS 提供了通过 HTTP API 实现域名解析的能力。针对无法直接集成官方 SDK 的场景,开发者可以自定义接入方式。本指南围绕可用性、性能、解析质量和安全性等关键方面,提供专业化建议,帮助开发者优化 HTTP API 的使用效果。

1. 可用性优化

场景:HTTPDNS 部分服务节点不可用

背景

在某些极端情况下,如自然灾害、运营商封禁或网络故障,HTTPDNS单个服务入口可能出现不可用的风险,导致对域名解析产生影响。

解决方案

  1. 启动 IP 冗余机制

    • 应用内嵌入多个启动 IP 或域名,确保始终与HTTPDNS服务保持连通性。

    • 请求失败时,自动切换使用下一个启动 IP。

  2. 服务 IP 动态更新

    通过向启动 IP 发起请求来获取服务 IP,更新服务IP的流程如下图所示:

image

有关调度接口的详细信息,请参阅如何获取解析服务地址

说明

建议在下列描述的场景中更新并保存服务IP列表:

  • 建议在App冷启动时进行更新。

  • 建议在切换网络环境时进行更新。

  • 建议每8小时至少更新一次。

  • 当服务IP列表经过重试发现都无法解析时,立即更新。

  1. 故障转移策略

    使用解析服务时,采用IP轮转机制,某个IP访问不通时轮转到下一个进行重试,避免某个服务IP无法使用时受到影响。在向服务端发起解析请求时,会从全局服务IP列表中获取一个可用的服务IP,只要当前IP可以解析,那么整个SDK生命周期都会使用这个IP解析,如果当前服务IP解析失败,则会切换全局服务IP列表中的下个IP重试一次。如果仍然失败则返回空,并且再次切换服务IP。

image
重要
  • 游标是全局的,并且建议将游标持久化保存在本地。

  • 服务IP列表只有出现解析失败的情况才会动态更新,通常是保持全局不变的。

  • 服务IP列表最好是动态可配置,这样可以减少覆盖生效的时间,缩小影响。

若所有 HTTPDNS 服务 IP 均请求失败,降级使用 Local DNS(即操作系统原生DNS链路)。如果是Android端使用了 OkHttp 网络库进行接入,降级使用 Local DNS 解析的方法如下:

List<InetAddress> result = okhttp3.Dns.SYSTEM.lookup(host);
val result: List<InetAddress> = Dns.SYSTEM.lookup(host)

如果是iOS端,只要不进行Host替换或者请求拦截即可,保持原有请求如下:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
// 发送请求
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error) {
        NSLog(@"error: %@", error);
    } else {
        NSLog(@"response: %@", response);
    }
}];
[task resume];
var request = URLRequest(url: url)
// 发送请求
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
    if let error = error {
        print("error: \(error)")
    } else {
        print("response: \(response?.description ?? "")")
    }
}
task.resume()
  1. 避免阻塞解析

    访问HTTPDNS服务时请做异步化处理,避免业务主流程同步等待网络解析过程。

2. 性能优化

场景:频繁查询导致性能瓶颈

背景

如果每次网络请求需要域名解析时,都向 HTTPDNS 服务发起请求,会显著增加业务耗时和带宽消耗。考虑到域名解析结果是有 TTL 缓存时间的,您可以基于这个值进行缓存。

解决方案

  1. 本地缓存

    • 根据DNS标准RFC104,可以按照TTL时间对解析结果进行缓存。

image
说明
  • TTL的值为HTTP API响应报文中的ttl字段。

  • 当缓存未命中或者已经过期时,则需要发起解析请求,并更新缓存。

  1. 预解析

说明

在缓存即将过期时(如 TTL 的 80%)提前解析相关域名并缓存到本地。在应用启动时,预解析常用域名并缓存结果。预解析能降低业务访问的延迟,但会增加一定的解析请求,建议只对热点域名使用该功能。

  1. 连接复用

    开启HTTP客户端的连接复用特性可以降低TCP连接建立的耗时,进而降低HTTPDNS的解析延迟。

  2. 持久化缓存

    可以把上一次解析到的结果进行持久化缓存,在 App 重启后,可以优先从持久层加载解析结果,这样可以提升首次加载速度。

说明
  • 存在第一次使用的IP为过期IP(TTL过期,大多数情况下该IP依然可以正常使用)的可能性。

  • 持久化缓存会影响“首次启动/网络切换”后域名解析结果,后续解析仍会请求HTTPDNS服务器,并更新本地缓存。

3. 解析质量优化

场景:跨运营商解析导致访问延迟

背景

在使用CDN域名,或域名配置了智能线路解析等场景,如果客户端根据 TTL 缓存了域名解析结果IP ,当网络环境发生变化(如4G切换到WIFI,或者WIFI切换到4G),新的网络环境和缓存的 IP 线路不匹配时,则可能导致业务网络请求性能问题。

解决方案

  1. 网络环境监听

    • 监测客户端网络变化(如从 Wi-Fi 切换到移动数据)。

    • 主动刷新本地缓存,确保解析结果适配当前网络环境。

重要

刷新所有域名的解析结果会产生一定流量消耗。

  1. 测速排序

    使用 ICMP 或 TCP 异步测试对解析结果排序,优先选择响应最快的 IP。

重要

此方法会影响原有业务服务器的负载均衡策略。

4. 安全性优化

场景:解析请求被劫持或泄露

背景

未使用鉴权机制的解析接口存在安全隐患,可能被第三方盗刷流量产生费用。

解决方案

  1. 鉴权解析

    解析接口建议使用鉴权解析,您可以在控制台设置开启/关闭非鉴权解析请求。

    • 需要使用鉴权解析的secretKey进行鉴权生成加密串,然后将生成的加密串携带在请求中,而secretKey无需在请求中携带,所以secretKey不会暴露,安全级别较高,确保解析请求中不暴露敏感信息。

    • 实现方式参考:实现鉴权访问

  2. HTTPS 安全通信

5. 问题排查建议

为了更高效地定位问题,您可以在 App 启动时,生成一个用于标识单个App生命周期的会话ID,在向HTTPDNS 发起请求时,附带该会话ID,则发生问题后,HTTPDNS 技术支持可以根据您提供的会话ID进行问题排查。会话ID格式定义为:[a-zA-Z0-9]{12} 。

例如:http://203.107.xxx.xxx/{accountId}/sign_d?host=www.aliyun.com&t=1573XXXX&s=60c7XXXXXX&sid=1234567890ab

6. 总结

通过遵循上述优化方案,开发者可以通过 API 在复杂网络环境中实现高可用、低延迟和安全的 HTTPDNS 接入,同时有效解决潜在问题,提升整体解析质量。