用阿里云 DNS SDK 实现动态域名解析

最近学 Java ,就将 Git 服,和测试服,直接放在家里的树莓派3和旧笔记本上,

为了在外网顺利访问,需要将域名动态的解析到家里的 IP 上,

网上了解了一番,觉得阿里云那套通过 sdk 来更新域名解析比较方面,正好手里也有阿里上购买的域名,

主要做的,就是拿到 ip ,

ipHtml = this.httpGet(requestUrl);

然后调用 api 更新域名

UpdateDomainRecordRequest updateRequest = new UpdateDomainRecordRequest();
// 设定类型
updateRequest.setType("A");
// 设置新的 IP
updateRequest.setValue(newIp);
// 域名
updateRequest.setRR(recordRRList.get(recordId));
// recordId
updateRequest.setRecordId(recordId);
// update
UpdateDomainRecordResponse updateResponse = client.getAcsResponse(updateRequest);

细节的处理比较啰嗦,主要是配置文件,缓存上次的 ip,多个子域名的处理,获取子域名的 record id

代码呢,我就直接贴上了,后面有我放在 Git 上的地址,有打好的包,和配置文件用例


import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DnsRefresh {

    private String propertyFile = "";

    DnsRefresh(String propertyFile) {
        this.propertyFile = propertyFile;
    }

    public void start() {

        System.out.print(" >>> " + propertyFile + "\n");
        Properties properties = this.getProperties();
        if (properties == null) {
            return;
        }

        // 要动态解析的子域名列表
        String[] domainArray = properties.getProperty("refreshDomain").split(",");
        // 旧的 IP
        String oldIp = properties.getProperty("oldIp");
        // IP 查询服务器
        String requestUrl = properties.getProperty("ipQueryServer");
        // 一级域名
        String rootDomain = properties.getProperty("rootDomain");
        // aliyun 配置
        String regionId = properties.getProperty("regionId");
        String accessKeyId = properties.getProperty("accessKeyId");
        String accessKeySecret = properties.getProperty("accessKeySecret");
        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);

        // 若报Can not find endpoint to access异常,请添加以下此行代码
        // DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "Alidns", "alidns.aliyuncs.com");
        IAcsClient client = new DefaultAcsClient(profile);

        // recordId 对应域名的列表
        Map recordRRList = new HashMap<>();

        // 获取子域名
        DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
        request.setDomainName(rootDomain);
        try {
            DescribeDomainRecordsResponse response = client.getAcsResponse(request);
            List recordList = response.getDomainRecords();
            for (DescribeDomainRecordsResponse.Record record : recordList) {
                // 只解析配置里的子域名
                if (Arrays.asList(domainArray).contains(record.getRR())) {
                    // 取得要解析的 record id
                    recordRRList.put(record.getRecordId(), record.getRR());
                }
            }
        } catch (ClientException e) {
            System.out.print(" >>> Error : "+ e.getMessage() + "\n");
        }

        // 预新的 IP 先和旧 IP 一样
        String newIp  = oldIp;
        String ipHtml;
        Pattern pattern = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)");
        Matcher m;
        UpdateDomainRecordRequest updateRequest = new UpdateDomainRecordRequest();

        // 每 30 秒循环一次
        while (true) {
            // 摘取页面
            ipHtml = this.httpGet(requestUrl);
            // 抓取成功
            if (ipHtml != null) {
                // IP 正则取出
                m = pattern.matcher(ipHtml);
                newIp = m.find() ? m.group(1) : newIp;
                // 如果 IP 发生了变化
                if (newIp != null && !newIp.equals(oldIp)) {
                    // 初始化更新域名解析的类
                    updateRequest.setType("A");
                    // 设置新的 IP
                    updateRequest.setValue(newIp);
                    // 将每个要解析的域名都处理一次
                    for (String recordId : recordRRList.keySet()) {
                        // 域名
                        updateRequest.setRR(recordRRList.get(recordId));
                        // recordId
                        updateRequest.setRecordId(recordId);
                        // print log
                        System.out.println("Try Update Domain : " + recordRRList.get(recordId) + "." + rootDomain + "\n");
                        try {
                            UpdateDomainRecordResponse updateResponse = client.getAcsResponse(updateRequest);
                            System.out.println("UpdateDomainRecordResponse : " + updateResponse + "\n");
                        } catch (ClientException e) {
                            System.out.println("client.getAcsResponse Error : " + e.getMessage() + "\n");
                        }
                    }
                    // 旧 IP 重新赋值
                    oldIp = newIp;
                }

                // 线程等待 10 秒
                synchronized (this) {
                    try {
                        this.wait(30 * 1000);
                    } catch (Exception e) {
                        System.out.println("System wait error : " + e.getMessage() + "\n");
                    }
                }
            }
        }
    }

    private String httpGet(String url) {
        HttpURLConnection http = null;
        InputStream is = null;
        try {
            URL urlGet = new URL(url);
            http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET");
            http.setRequestProperty("Content-Type", "text/html; charset=UTF-8");
            http.setDoOutput(true);
            http.setDoInput(true);
            http.connect();
            is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            return new String(jsonBytes, "UTF-8");
        }
        catch (Exception e) {
            return null;
        }
    }


    private Properties getProperties() {
        try {
            InputStream is = new FileInputStream(propertyFile);
            Properties pros = new Properties();
            pros.load(is);
            return pros;
        } catch (IOException e) {
            System.out.println(propertyFile + " is can not read \n");
        }
        return null;
    }
}

项目的  Github 地址 https://github.com/koocyton/AliDnsRefresh ,打好的包也在里面

我是一个 Java 新手,多多指教

如何获取AccessKeyId和AccessKeySecret ? 参考 https://helpcdn.aliyun.com/knowledge_detail/48699.html

我的内容比较粗糙,http://blog.csdn.net/jiyuxian/article/details/53762646 说的比较详细

你可能感兴趣的:(Java)