前景说明:
你有一个阿里云的域名,想让它解析到你家用宽带动态ip上。
解决思路:
1、定时查看宽带的ip;
2、发现变化时,通过阿里云提供的sdk修改域名解析。
一、阿里云控制台创建AccessKey
官方文档:创建阿里云AccessKey_访问控制(RAM)-阿里云帮助中心 (aliyun.com)
二、阿里云 云解析
官方文档:云解析_SDK中心-阿里云OpenAPI开发者门户 (aliyun.com)
官方接口:UpdateDomainRecord_云解析_API调试-阿里云OpenAPI开发者门户 (aliyun.com)
DescribeDomainRecordInfo_云解析_API调试-阿里云OpenAPI开发者门户
三、上代码
1、pom.xml引包
<dependencies>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alidns20150109</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>0.3.0</version>
</dependency>
</dependencies>
2、获取外网ip的方法
package com.chhuang;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.regex.Pattern;
public class ExternalIPUtil {
/**
* IP 地址校验的正则表达式
*/
private static final Pattern IPV4_PATTERN = Pattern.compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
/**
* 获取 IP 地址的服务列表
*/
private static final String[] IPV4_SERVICES = {
"http://checkip.amazonaws.com/",
"https://ipv4.icanhazip.com/",
"http://bot.whatismyipaddress.com/"
// and so on ...
};
// 线程池的 ExecutorService.invokeAny(callables) 方法用于并发执行多个线程,并拿到最快的执行成功的线程的返回值,
// 只要有一个执行成功,其他失败的任务都会忽略。但是如果全部失败,
// 例如本机根本就没有连外网,那么就会抛出 ExecutionException 异常。
public static String get() throws ExecutionException, InterruptedException {
List<Callable<String>> callables = new ArrayList<>();
for (String ipService : IPV4_SERVICES) {
callables.add(() -> get(ipService));
}
ExecutorService executorService = Executors.newCachedThreadPool();
try {
// 返回第一个成功获取的 IP
return executorService.invokeAny(callables);
} finally {
executorService.shutdown();
}
}
private static String get(String url) throws IOException {
try (BufferedReader in = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
String ip = in.readLine();
if (IPV4_PATTERN.matcher(ip).matches()) {
return ip;
} else {
throw new IOException("invalid IPv4 address: " + ip);
}
}
}
}
3、使用云解析
package com.chhuang;
import com.aliyun.alidns20150109.Client;
import com.aliyun.alidns20150109.models.DescribeDomainRecordInfoRequest;
import com.aliyun.alidns20150109.models.DescribeDomainRecordInfoResponse;
import com.aliyun.alidns20150109.models.UpdateDomainRecordRequest;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import java.util.Random;
/**
* Hello world!
*
*/
public class App {
private static final String APP_ALIBABA_ID = "你自己的ALIBABA_CLOUD_ACCESS_KEY_ID";
private static final String SECURITY_ALIBABA_KEY = "你自己的ALIBABA_CLOUD_ACCESS_KEY_SECRET";
/**
* 使用AK&SK初始化账号Client
* @return Client
* @throws Exception
*/
public static Client createClient() throws Exception {
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
// 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
Config config = new Config()
.setAccessKeyId(APP_ALIBABA_ID)
.setAccessKeySecret(SECURITY_ALIBABA_KEY);
// Endpoint 请参考 https://api.aliyun.com/product/Alidns
config.endpoint = "alidns.cn-hangzhou.aliyuncs.com";
return new Client(config);
}
public static void main( String[] args ) throws Exception {
while (true) {
Random random = new Random();
Thread.sleep((random.nextInt(600) + 600) * 1000);
// 获取外网ip
String ip = ExternalIPUtil.get();
System.out.println("ip=" + ip);
// 更新域名解析
updateDomain(ip);
}
}
private static void updateDomain(String ip) throws Exception {
Client client = App.createClient();
// 获取解析记录的详细信息
DescribeDomainRecordInfoRequest describeDomainRecordInfoRequest = new DescribeDomainRecordInfoRequest()
.setRecordId("你自己域名解析记录的recordId");
RuntimeOptions runtime = new RuntimeOptions();
try {
// 复制代码运行请自行打印 API 的返回值
DescribeDomainRecordInfoResponse response = client.describeDomainRecordInfoWithOptions(describeDomainRecordInfoRequest, runtime);
String value = response.getBody().getValue();
// 判断 ip 是否需要修改
if (!ip.equals(value)) {
UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest()
.setRecordId("你自己域名解析记录的recordId") // 通过阿里云后台,DescribeDomainRecords 获取解析记录
.setRR("www")
.setType("A")
.setValue(ip)
.setTTL(600L);
// 复制代码运行请自行打印 API 的返回值
client.updateDomainRecordWithOptions(updateDomainRecordRequest, runtime);
}
} catch (TeaException error) {
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
error.printStackTrace();
// 诊断地址
System.out.println(error.getData().get("Recommend"));
Common.assertAsString(error.message);
} catch (Exception _error) {
_error.printStackTrace();
TeaException error = new TeaException(_error.getMessage(), _error);
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 诊断地址
System.out.println(error.getData().get("Recommend"));
Common.assertAsString(error.message);
}
}
}