阿里云DDNS动态绑定域名与IP实现远程调试远程办公

之前申请了公网IP,这样调试接口的时候可以直接远程调试,但因为申请的公网IP会随时变化,所以使用阿里云DDNS服务,随时绑定公网IP,直接域名访问服务。

1.创建阿里云账号和访问密钥(AccessKey)

AccessKey是您访问阿里云API的密钥,使用阿里SDK进行操作必须先获取AccessKey!

创建地址:https://usercenter.console.aliyun.com/

在这里插入图片描述

因为主账号权限过于强大,所以尽量使用子账号AccessKey并赋予需要使用的权限,这里我们点击“开始使用子账号AccessKey”。

在这里插入图片描述
这里我们进行简单操作,直接点击创建用户即可

在这里插入图片描述

名称随意,控制台权限随意,但要注意选择OpenAPI访问!
在这里插入图片描述

创建成功后,需要添加AccessKey,点击创建。
在这里插入图片描述
注意:创建成功后一定要记住AccessKey等相关信息,如果忘记,只能创建新的key代替!

在这里插入图片描述
之后点击权限管理,添加权限!

在这里插入图片描述
找到“管理云解析(DNS)的权限”添加即可。

2.使用SDK绑定动态IP绑定

创建Maven项目并加入阿里云SDK依赖

<dependencies>
     <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core -->
     <dependency>
         <groupId>com.aliyun</groupId>
         <artifactId>aliyun-java-sdk-core</artifactId>
         <version>4.4.3</version>
     </dependency>
     <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-alidns -->
     <dependency>
         <groupId>com.aliyun</groupId>
         <artifactId>aliyun-java-sdk-alidns</artifactId>
         <version>2.0.10</version>
     </dependency>
</dependencies>

示例代码:

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsRequest;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsResponse;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordRequest;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 动态域名解析
 */
public class DDNS {

    /**
     * 获取主域名的所有解析记录列表
     */
    private DescribeDomainRecordsResponse describeDomainRecords(DescribeDomainRecordsRequest request, IAcsClient client){
        try {
            // 调用SDK发送请求
            return client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
            // 发生调用错误,抛出运行时异常
            throw new RuntimeException();
        }
    }

    /**
     * 获取当前主机公网IP
     */
    private String getCurrentHostIP(){
        // 这里使用jsonip.com第三方接口获取本地IP
        String jsonip = "https://jsonip.com/";
        // 接口返回结果
        String result = "";
        BufferedReader in = null;
        try {
            // 使用HttpURLConnection网络请求第三方接口
            URL url = new URL(jsonip);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();
            in = new BufferedReader(new InputStreamReader(
                    urlConnection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }

        }
        // 正则表达式,提取xxx.xxx.xxx.xxx,将IP地址从接口返回结果中提取出来
        String rexp = "(\\d{1,3}\\.){3}\\d{1,3}";
        Pattern pat = Pattern.compile(rexp);
        Matcher mat = pat.matcher(result);
        String res="";
        while (mat.find()) {
            res=mat.group();
            break;
        }
        return res;
    }

    /**
     * 修改解析记录
     */
    private UpdateDomainRecordResponse updateDomainRecord(UpdateDomainRecordRequest request, IAcsClient client){
        try {
            // 调用SDK发送请求
            return client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
            // 发生调用错误,抛出运行时异常
            throw new RuntimeException();
        }
    }

    private static void log_print(String functionName, Object result) {
        Gson gson = new Gson();
        System.out.println("-------------------------------" + functionName + "-------------------------------");
        System.out.println(gson.toJson(result));
    }

    public static void main(String[] args) {
        // 设置鉴权参数,初始化客户端
        DefaultProfile profile = DefaultProfile.getProfile(
                "cn-qingdao",// 地域ID
                "your-access-key-id",// 您的AccessKey ID
                "your-access-key-secret");// 您的AccessKey Secret
        IAcsClient client = new DefaultAcsClient(profile);

        DDNS ddns = new DDNS();

        // 查询指定二级域名的最新解析记录
        DescribeDomainRecordsRequest describeDomainRecordsRequest = new DescribeDomainRecordsRequest();
        // 主域名
        describeDomainRecordsRequest.setDomainName("example.com");
        // 主机记录
        describeDomainRecordsRequest.setRRKeyWord("ddnstest");
        // 解析记录类型
        describeDomainRecordsRequest.setType("A");
        DescribeDomainRecordsResponse describeDomainRecordsResponse = ddns.describeDomainRecords(describeDomainRecordsRequest, client);
        log_print("describeDomainRecords",describeDomainRecordsResponse);

        List<DescribeDomainRecordsResponse.Record> domainRecords = describeDomainRecordsResponse.getDomainRecords();
        // 最新的一条解析记录
        if(domainRecords.size() != 0 ){
            DescribeDomainRecordsResponse.Record record = domainRecords.get(0);
            // 记录ID
            String recordId = record.getRecordId();
            // 记录值
            String recordsValue = record.getValue();
            // 当前主机公网IP
            String currentHostIP = ddns.getCurrentHostIP();
            System.out.println("-------------------------------当前主机公网IP为:"+currentHostIP+"-------------------------------");
            if(!currentHostIP.equals(recordsValue)){
                // 修改解析记录
                UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest();
                // 主机记录
                updateDomainRecordRequest.setRR("ddnstest");
                // 记录ID
                updateDomainRecordRequest.setRecordId(recordId);
                // 将主机记录值改为当前主机IP
                updateDomainRecordRequest.setValue(currentHostIP);
                // 解析记录类型
                updateDomainRecordRequest.setType("A");
                UpdateDomainRecordResponse updateDomainRecordResponse = ddns.updateDomainRecord(updateDomainRecordRequest, client);
                log_print("updateDomainRecord",updateDomainRecordResponse);
            }
        }
    }
}

此处注意,有四个地方需要改动:
your-access-key-id,your-access-key-secret,这两处对应了之前申请的AccessKey,填写即可。
example.com:这里需要修改为申请的域名,直接修改即可。
ddnstest:主机记录,按照域名解析设置中填写即可
在这里插入图片描述
直接执行即可,免去手动修改域名。

如果有服务器不停机的需求,还可以直接使用定时任务循环之形态吗,检测到域名更改则重新绑定:

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsRequest;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsResponse;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordRequest;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 动态域名解析
 */
public class DDNS {

  /**
   * 获取主域名的所有解析记录列表
   */
  private DescribeDomainRecordsResponse describeDomainRecords(DescribeDomainRecordsRequest request, IAcsClient client){
    try {
      // 调用SDK发送请求
      return client.getAcsResponse(request);
    } catch (ClientException e) {
      e.printStackTrace();
      // 发生调用错误,抛出运行时异常
      throw new RuntimeException();
    }
  }

  /**
   * 获取当前主机公网IP
   */
  private String getCurrentHostIP(){
    // 这里使用jsonip.com第三方接口获取本地IP
    String jsonip = "https://jsonip.com/";
    // 接口返回结果
    String result = "";
    BufferedReader in = null;
    try {
      // 使用HttpURLConnection网络请求第三方接口
      URL url = new URL(jsonip);
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
      urlConnection.setRequestMethod("GET");
      urlConnection.connect();
      in = new BufferedReader(new InputStreamReader(
          urlConnection.getInputStream()));
      String line;
      while ((line = in.readLine()) != null) {
        result += line;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    // 使用finally块来关闭输入流
    finally {
      try {
        if (in != null) {
          in.close();
        }
      } catch (Exception e2) {
        e2.printStackTrace();
      }

    }
    // 正则表达式,提取xxx.xxx.xxx.xxx,将IP地址从接口返回结果中提取出来
    String rexp = "(\\d{1,3}\\.){3}\\d{1,3}";
    Pattern pat = Pattern.compile(rexp);
    Matcher mat = pat.matcher(result);
    String res="";
    while (mat.find()) {
      res=mat.group();
      break;
    }
    return res;
  }

  /**
   * 修改解析记录
   */
  private UpdateDomainRecordResponse updateDomainRecord(UpdateDomainRecordRequest request, IAcsClient client){
    try {
      // 调用SDK发送请求
      return client.getAcsResponse(request);
    } catch (ClientException e) {
      e.printStackTrace();
      // 发生调用错误,抛出运行时异常
      throw new RuntimeException();
    }
  }

  public static void checkIP()
  {
    System.err.println("————————————————————————————————————————————————————————————————————————————————————————————————————");
    System.err.println("任务开始,当前时间为:"+ LocalDateTime.now());
    // 设置鉴权参数,初始化客户端
    DefaultProfile profile = DefaultProfile.getProfile(
        "cn-qingdao",// 地域ID
        "",// 您的AccessKey ID
        "");// 您的AccessKey Secret
    IAcsClient client = new DefaultAcsClient(profile);
    DDNS ddns = new DDNS();
    // 查询指定二级域名的最新解析记录
    DescribeDomainRecordsRequest describeDomainRecordsRequest = new DescribeDomainRecordsRequest();
    // 主域名
    describeDomainRecordsRequest.setDomainName("");
    // 主机记录
    describeDomainRecordsRequest.setRRKeyWord("@");
    // 解析记录类型
    describeDomainRecordsRequest.setType("A");
    DescribeDomainRecordsResponse describeDomainRecordsResponse = ddns.describeDomainRecords(describeDomainRecordsRequest, client);
    List<DescribeDomainRecordsResponse.Record> domainRecords = describeDomainRecordsResponse.getDomainRecords();
    // 最新的一条解析记录
    if(domainRecords.size() != 0 ){
      DescribeDomainRecordsResponse.Record record = domainRecords.get(0);
      // 记录ID
      String recordId = record.getRecordId();
      // 记录值
      String recordsValue = record.getValue();
      // 当前主机公网IP
      String currentHostIP = ddns.getCurrentHostIP();
      System.err.println("云解析IP为:"+recordsValue);
      System.err.println("当前主机公网IP为:"+currentHostIP);
      if(!currentHostIP.equals(recordsValue)){
        // 修改解析记录
        UpdateDomainRecordRequest updateDomainRecordRequest = new UpdateDomainRecordRequest();
        // 主机记录
        updateDomainRecordRequest.setRR("@");
        // 记录ID
        updateDomainRecordRequest.setRecordId(recordId);
        // 将主机记录值改为当前主机IP
        updateDomainRecordRequest.setValue(currentHostIP);
        // 解析记录类型
        updateDomainRecordRequest.setType("A");
        UpdateDomainRecordResponse updateDomainRecordResponse = ddns.updateDomainRecord(updateDomainRecordRequest, client);
        System.err.println("云解析IP更新成功");
      }else{
        System.err.println("IP相同无需更新");
      }
    }
  }

  public static void main(String[] args) {
    // 创建一个ScheduledThreadPoolExecutor线程池,核心线程数为5
    ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
    // 创建Runnable打印当前线程和当前时间
    Runnable r = () -> checkIP();

    // 在指定1秒延迟后执行r,之后每30秒执行一次
    scheduledExecutorService.scheduleAtFixedRate(r, 1, 30, TimeUnit.SECONDS);
  }
}

在这里插入图片描述
后台执行即可!

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值