你有一个阿里云的域名,想让它解析到你家用宽带动态ip上。
1、定时查看宽带的ip;
2、发现变化时,通过阿里云提供的sdk修改域名解析。
官方文档:创建阿里云AccessKey_访问控制(RAM)-阿里云帮助中心 (aliyun.com)
官方文档:云解析_SDK中心-阿里云OpenAPI开发者门户 (aliyun.com)
官方接口:UpdateDomainRecord_云解析_API调试-阿里云OpenAPI开发者门户 (aliyun.com)
DescribeDomainRecordInfo_云解析_API调试-阿里云OpenAPI开发者门户
- <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>
- 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
> 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);
- }
- }
- }
- }
- 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);
- }
- }
- }