用阿里雲 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<String, String> recordRRList = new HashMap<>();
 
        // 獲取子域名
        DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
        request.setDomainName(rootDomain);
        try {
            DescribeDomainRecordsResponse response = client.getAcsResponse(request);
            List<DescribeDomainRecordsResponse.Record> 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 說的比較詳細
————————————————
版權聲明:本文為CSDN博主「koocyton」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/koocyton/article/details/79331305


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM