其实在工作中有遇到过几种情况,一种是域名变更解析地址,但是生效时间是不定的,存在一定的延迟。

其次,每次的请求,都会走运营商 Local DNS,那么这时候有可能会被DNS劫持。

而且,运营商DNS解析有时候会影响到请求速度的,当运营商DNS解析慢的时候,软件也会受到一定的影响。

但是当客户端直接通过ip访问后就不会有这个问题了,阿里有个产品叫 HTTPDNS,可以解析出域名ip地址 。

首先在阿里云的控制台开通HTTPDNS,并且获得所需要的account id 。

并且在域名列表添加需要的域名,首次添加的域名,需要等一段时间才能生效。

httpdns-1

以下以Android端为例子,话说我已经好久没碰Android了...

在 build.gradle中添加Maven仓库地址

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
        }
        
    }
}

在app.gradle 文件中添加依赖

dependencies {

    compile ('com.aliyun.ams:alicloud-android-httpdns:1.3.1@aar') {
        transitive true
    }
}

获取httpdns实例,一参是Context 对象,即Android 中的上下文对象。

httpDnsService = HttpDns.getService(this, "xxxxxx");

设置预热域名,可以选择性地预先向HTTPDNS SDK中注册后续可能会使用到的域名,以便SDK提前解析,减少后续解析域名时请求的时延。

httpDnsService.setPreResolveHosts((ArrayList<String>) Arrays.asList("xxx.xxxx.io"));

获取ip地址

String ipAddress = httpDnsService.getIpByHostAsync(doman);

如果是用的okhttp作为底层的http通讯组件的话,有很好的接入方式。okhttp提供了dns的接口,我们自定义接口即可。

public class OkHttpDns implements Dns {
    private static final Dns SYSTEM = Dns.SYSTEM;
    HttpDnsService httpdns;//httpdns 解析服务
    private static OkHttpDns instance = null;

    private OkHttpDns(Context context) {
        this.httpdns = HttpDns.getService(context, "account id");
    }

    public static OkHttpDns getInstance(Context context) {
        if (instance == null) {
            instance = new OkHttpDns(context);
        }
        return instance;
    }

    @Override
    public List<InetAddress> lookup(String hostname) throws UnknownHostException {
        //通过异步解析接口获取ip
        String ip = httpdns.getIpByHostAsync(hostname);
        if (ip != null) {
            //如果ip不为null,直接使用该ip进行网络请求
            List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
            Log.e("OkHttpDns", "inetAddresses:" + inetAddresses);
            return inetAddresses;
        }
        //如果返回null,走系统DNS服务解析域名
        return Dns.SYSTEM.lookup(hostname);
    }
}

经我实际测试,在对域名更换A解析后,TTL时间生效后,Android端能获得最新的ip地址。

我用的是免费版的域名解析,TTL最小是10分钟,也就是说免费版的话,最少也需要10分钟生效,不过也比运营商的缓存好多了,很多时候更改解析后,运营商那边半个多小时都不一定能更新缓存。

当然,也可以选择升级域名解析,比如这个企业旗舰版,TTL能达到1秒。

httpdns-2