All Products
Search
Document Center

Alibaba Cloud DNS:Panduan Pengembangan SDK Android

Last Updated:Mar 18, 2026

Dokumen ini menjelaskan cara mengintegrasikan SDK Android HTTPDNS.

Ikhtisar

SDK Android merupakan wrapper Java untuk DoH JSON API HTTPDNS. SDK ini menyediakan antarmuka Java bagi aplikasi Android untuk melakukan resolusi nama domain dan mencakup cache lokal yang efisien berdasarkan kebijakan TTL dan LRU. Developer dapat mengintegrasikan HTTPDNS ke dalam aplikasi Android mereka guna mengatasi error resolusi nama domain dan mencapai penjadwalan akurat dengan biaya rendah.

SDK ini menawarkan keunggulan berikut:

  • Simple to use

    Anda hanya perlu mengintegrasikan SDK yang disediakan untuk mengakses layanan HTTPDNS. Metode integrasinya sederhana dan memberikan pengalaman resolusi yang mudah serta nyaman.

  • Zero latency

    SDK menerapkan cache LRU yang menyimpan alamat IP hasil resolusi secara lokal. Cache tersebut secara proaktif memperbarui entri yang TTL-nya telah kedaluwarsa agar data tetap mutakhir dan efektif. Hal ini memungkinkan resolusi nama domain tanpa latensi.

Untuk panduan implementasi, lihat kode sumber proyek contoh alidns_android_demo.

Integrasikan SDK

Integrasikan SDK

Integrasikan menggunakan Gradle dengan Maven

Tambahkan kode berikut ke file build.gradle Anda:

allprojects {
  repositories {
    maven {
      url 'https://maven.aliyun.com/repository/public/'
    }
    mavenLocal()
    mavenCentral()
  }
}

Tambahkan informasi untuk berkas yang ingin Anda rujuk:

dependencies {
     implementation 'com.alibaba.pdns:alidns-android-sdk:2.3.0'
     implementation 'com.google.code.gson:gson:2.8.5'
}

Integrasikan menggunakan file AAR

Lihat Unduh SDK untuk mendapatkan file alidns_android_sdk.aar dan integrasikan ke direktori `libs` proyek Anda.

Catatan

Anda dapat memilih salah satu metode integrasi untuk proyek Anda.

Inisialisasi SDK

Penting

Inisialisasi SDK sedini mungkin untuk menghindari kegagalan saat melakukan resolusi alamat IP.

Pertama, identifikasi Account ID Anda di konsol dan buat kunci untuk mendapatkan AccessKey ID dan AccessKey Secret Anda. Kemudian integrasikan dan inisialisasi SDK. Untuk petunjuk inisialisasi spesifik, lihat contoh kode pada bagian Application.

public class DnsCacheApplication extends Application{

    private String accountId = "Your Account ID"; // Tetapkan Account ID yang digunakan untuk mengakses SDK di konsol.
    private String accessKeyId = "Your AccessKey ID"; // Tetapkan AccessKey ID yang digunakan untuk mengakses SDK di konsol.
    private String accessKeySecret = "Your AccessKey secret"; // Tetapkan AccessKey secret yang digunakan untuk mengakses SDK di konsol.

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,accountId,accessKeyId,accessKeySecret); // Tetapkan Account ID, AccessKey ID, dan AccessKey secret yang digunakan untuk mengakses SDK di konsol.
       // Catatan: Jika Anda mengonfigurasi nama domain yang akan disimpan dalam cache, resolusi akan dipicu secara otomatis ketika 75% TTL telah berlalu. Ini memastikan bahwa resolusi nama domain yang dikonfigurasi selalu mengenai cache. Namun, jika Anda menggunakan CDN, nilai TTL mungkin kecil. Hal ini mengakibatkan banyak permintaan resolusi dan meningkatkan biaya. Gunakan metode ini dengan hati-hati.
       DNSResolver.setKeepAliveDomains(new String[]{"The domain name to be kept in the cache 1","The domain name to be kept in the cache 2",...});
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"The domain name to be pre-resolved 1","The domain name to be pre-resolved 2",...}); // Tetapkan nama domain tipe IPv4 tertentu untuk pra-resolusi. Ganti nama domain pra-resolusi dengan nama domain yang ingin Anda selesaikan menggunakan Alibaba Cloud DNS.
    }
}
Catatan

DNSResolver adalah kelas inti dari SDK HTTPDNS. Kelas ini membungkus DoH JSON API yang disediakan oleh HTTPDNS untuk mengubah nama domain target pengguna menjadi alamat IP yang sesuai. Saat mengintegrasikan SDK HTTPDNS, kami merekomendasikan untuk mengintegrasikannya di kelas turunan Application.

Aplikasi Android Anda juga harus mendeklarasikan izin berikut:

<!--Required permissions-->
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Otentikasi SDK

Mulai versi 2.0, SDK ini mendukung otentikasi untuk melindungi keamanan identitas pengguna dan mencegah penyalahgunaan oleh pihak ketiga yang tidak sah. Untuk mengaktifkan otentikasi, lihat Buat Kunci untuk membuat AccessKey ID dan AccessKey Secret di konsol. Jika Anda tidak mengonfigurasi parameter otentikasi selama inisialisasi SDK, HTTPDNS akan menolak permintaan resolusi nama domain tanpa otentikasi. Hal ini menonaktifkan fungsi resolusi nama domain dan memengaruhi operasi bisnis Anda. Oleh karena itu, Anda harus mengonfigurasi parameter otentikasi saat menginisialisasi SDK HTTPDNS.

Tetapkan parameter otentikasi sebagai berikut:

DNSResolver.Init(this,accountId,accessKeyId,accessKeySecret);
Peringatan
  • Untuk mencegah parameter sensitif seperti Account ID, AccessKey ID, atau AccessKey secret—atau data yang dihasilkan selama runtime aplikasi—muncul di log, nonaktifkan logging debug SDK pada build produksi.

  • Karena semua pengguna mengintegrasikan SDK yang sama, Anda harus menetapkan Account ID, AccessKey ID, dan AccessKey secret dalam kode Anda. Parameter-parameter ini terkait dengan metering dan penagihan. Untuk mencegah eksposur akibat dekompilasi jahat, aktifkan obfuscation dan perkuat aplikasi Anda sebelum dipublikasikan.

Permasalahan umum integrasi SDK

Android 9.0 melemparkan "cleartext HTTP traffic not permitted" saat mengirim permintaan HTTP

Penyebab: Mulai Android 9.0 (API level 28), Android secara default memblokir lalu lintas jaringan cleartext dan hanya mengizinkan URL HTTPS.

Solusi

Tambahkan baris berikut ke elemen <application> dalam file AndroidManifest.xml Anda:

android:usesCleartextTraffic="true"

<application
        android:name=".DnsCacheApplication"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true">

Android 9.0 melemparkan "Didn't find class BasicHttpParams"

Penyebab: Apache HTTP client sudah ditinggalkan.

Google menghapus dukungan untuk Apache HTTP client di Android 6.0. Mulai Android 9.0, org.apache.http.legacy dihapus dari bootclasspath.

Perubahan ini tidak memengaruhi sebagian besar aplikasi dengan taskVersion kurang dari 9.0. Untuk aplikasi dengan taskVersion lebih dari 9.0, akan terjadi pengecualian "Apache HTTP interface not found" jika antarmuka Apache HTTP digunakan, baik secara langsung maupun melalui paket library yang direferensikan.

Solusi

Tambahkan baris berikut ke elemen <application> dalam file AndroidManifest.xml Anda:

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

SDK ini memperkenalkan JNI mulai versi 2.1.9. Konfigurasikan NDK di proyek aplikasi Anda

  • Tambahkan path instalasi NDK ke file local.properties di direktori root proyek aplikasi Anda:

ndk.dir=...\\ndk\\21.4.7075529; // ... adalah path instalasi NDK lokal
  • Tambahkan konfigurasi berikut ke file gradle.properties di direktori root proyek aplikasi Anda:

android.useDeprecatedNdk = true;

Jika proyek aplikasi Anda sudah memiliki konfigurasi NDK, lewati langkah ini. Untuk hasil terbaik, kompilasi aplikasi Anda menggunakan JDK 1.8 dan NDK 21.4.7075529.

Referensi API

Pengaturan umum

1. Inisialisasi menggunakan metode Init

Panggil metode Init saat menginisialisasi SDK di kelas Application Anda.

DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret);

2. Tetapkan nama domain untuk pra-resolusi

Saat menginisialisasi program Anda, kami sangat menyarankan untuk mendaftarkan terlebih dahulu nama domain yang akan digunakan ke SDK HTTPDNS. Hal ini memungkinkan SDK melakukan resolusi nama domain lebih awal dan mengurangi latensi permintaan resolusi berikutnya. Panggil metode berikut untuk menetapkan nama domain yang akan di-pra-resolusi:

  • Tentukan pra-resolusi IPv4 atau IPv6

// Tetapkan tipe nama domain tertentu untuk pra-resolusi. Ganti nama domain pra-resolusi dengan nama domain yang ingin Anda selesaikan menggunakan Alibaba Cloud DNS.
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...});

// DNSResolver.QTYPE_IPV4: Tipe catatan IPv4 untuk pra-resolusi.
// DNSResolver.QTYPE_IPV6: Tipe catatan IPv6 untuk pra-resolusi.
// DNSResolver.QTYPE_IPV4_IPV6: Tipe catatan IPv4 dan IPv6 untuk pra-resolusi.
  • Deteksi otomatis lingkungan jaringan saat ini. Di jaringan dual-stack, pra-resolusi nama domain IPv4 dan IPv6 dilakukan bersamaan.

DNSResolver.getInstance().preLoadDomains(domains);
Penting

Antarmuka pra-resolusi memicu permintaan jaringan asinkron secara real-time. Pastikan semua langkah inisialisasi yang diperlukan telah selesai sebelum memanggil antarmuka ini.

3. Tetapkan domain untuk keep-alive cache

SDK secara otomatis melakukan resolusi ulang domain yang dikonfigurasi ketika 75% TTL-nya telah berlalu. Hal ini memastikan permintaan resolusi selalu mengenai cache dan meningkatkan efisiensi resolusi. Batasi hingga maksimal 10 domain. Pengaturan ini independen dari pra-resolusi.

DNSResolver.setKeepAliveDomains(new String[]{"User-specified domain name 1", "User-specified domain name 2"});
Catatan

Manfaat

1. Catatan diperbarui sebelum TTL kedaluwarsa.

2. Saat digunakan bersama pra-pemuatan, latensi parsing awal dapat dikurangi hingga 0 ms.

Kerugian

1. Resolusi ulang pada 75% TTL menimbulkan biaya tambahan.

4. Aktifkan atau nonaktifkan alamat server IPv6

HTTPDNS mendukung akses alamat dual-stack IPv4 dan IPv6. Gunakan metode DNSResolver.setEnableIPv6(boolean enable) untuk mengonfigurasi apakah akan menggunakan alamat IPv6 sisi server. Ketika parameter ini diatur ke true, layanan menggunakan alamat IPv6 untuk mengakses antarmuka sisi server. Ketika diatur ke false, layanan menggunakan alamat IPv4. Jika Anda tidak secara eksplisit mengonfigurasi pengaturan ini, layanan secara default menggunakan IPv4. Selain itu, jika Anda mengaktifkan IPv6 dan layanan HTTPDNS tidak dapat dijangkau, Automatic Failover beralih ke alamat IPv4 dan mendukung satu kali percobaan ulang.

5. Tetapkan ukuran maksimum cache

DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); // Menetapkan jumlah maksimum entri cache. Nilai default adalah 100.

Anda dapat menyesuaikan jumlah maksimum tersebut.

6. Tetapkan protokol untuk akses server

SDK mendukung konfigurasi tipe protokol permintaan HTTP untuk resolusi DNS, memungkinkan Anda memilih antara HTTP dan HTTPS. Secara default, SDK menggunakan HTTPS untuk resolusi DNS karena memberikan keamanan yang lebih baik.HTTPDNS Penagihan didasarkan pada permintaan resolusi HTTP, sedangkan resolusi HTTPS ditagih lima kali lipat dari lalu lintas HTTP. Pilih tipe protokol permintaan HTTP berdasarkan kebutuhan bisnis Anda.

DNSResolver.setSchemaType(DNSResolver.HTTPS); // Mode akses default adalah HTTPS.

DNSResolver.HTTP: Mengakses antarmuka sisi server melalui HTTP.

DNSResolver.HTTPS: Mengakses antarmuka sisi server melalui HTTPS.

7. Tetapkan nomor port untuk pengujian kecepatan IP

DNSResolver.setSpeedPort(DNSResolver.PORT_80);

Anda dapat menetapkan nomor port untuk probing IP berbasis socket. Nilai default adalah 80.

Pengaturan lanjutan lainnya

1. Aktifkan atau nonaktifkan logging debug SDK

DNSResolver.setEnableLogger(true); // Log debug SDK dinonaktifkan secara default

Atur ke true untuk mengaktifkan log debug atau false untuk menonaktifkannya.

2. Tetapkan apakah akan mengaktifkan HTTPDNS secara otomatis menurunkan spesifikasi ke DNS lokal untuk resolusi fallback ketika parsing gagal

DNSResolver.setEnableLocalDns(true); // Secara default, fallback otomatis ke resolusi LocalDNS diaktifkan ketika resolusi HTTPDNS gagal.

3. Aktifkan atau nonaktifkan mode singkat

DoH JSON API HTTPDNS mengembalikan data dalam dua format: format JSON lengkap dan format array IP sederhana. Anda dapat memanggil DNSResolver.setEnableShort(boolean enable) untuk mengaktifkan atau menonaktifkan mode singkat. Jika Anda tidak mengonfigurasi DNSResolver.setEnableShort(boolean enable), mode singkat dinonaktifkan secara default, sebagai berikut:

DNSResolver.setEnableShort(true); // Nilai default adalah false. Anda tidak perlu menyetel parameter ini.
Penting

Dalam mode singkat, SDK memanggil layanan HTTPDNS dan mengembalikan array alamat IP yang lebih sederhana. Hal ini mengurangi volume data respons dan cocok untuk skenario yang sensitif terhadap lalu lintas jaringan.

4. Aktifkan atau nonaktifkan cache yang tidak pernah kedaluwarsa

DNSResolver.setImmutableCacheEnable(false); // Secara default, cache immutable (cache yang tidak pernah kedaluwarsa) dinonaktifkan
Penting

SDK menyediakan tiga mekanisme pembaruan cache:

  • Cache Tidak Pernah Kedaluwarsa: Setelah Anda mengaktifkan fitur ini, cache selalu dianggap valid selama aplikasi berjalan. Pemeriksaan dan pembaruan kedaluwarsa cache tidak dilakukan. Anda tidak perlu memanggil setKeepAliveDomains untuk memperbarui cache secara manual. Hal ini meminimalkan jumlah permintaan resolusi DNS.

    Cara menyetel: DNSResolver.setImmutableCacheEnable(boolean var0)

    Deskripsi parameter: Ketika parameter var0 bernilai true, fitur cache tidak pernah kedaluwarsa diaktifkan. Ketika var0 bernilai false, fitur dinonaktifkan.

  • Pembaruan cache aktif: Ketika TTL domain keep-alive turun menjadi 75% dari nilai aslinya, SDK memicu resolusi baru untuk memperbarui cache. Hal ini mengurangi latensi dan menjaga catatan tetap mutakhir ketika zona otoritatif berubah. Maksimal 10 nama domain.

    Cara menyetel: DNSResolver.setKeepAliveDomains(String[] var1)

    Deskripsi metrik: var1 adalah array string nama domain yang akan diperbarui secara aktif.

  • Pembaruan cache pasif:

    Ketika Anda memanggil dua metode berikut untuk mengambil hasil parsing, cache diperbarui secara otomatis:

    • getIPsV4ByHost(String hostName) mengambil array catatan IPv4 untuk hostName. Jika cache tidak kosong dan masih dalam periode validitas TTL, metode ini mengembalikan hasil dari cache. Jika tidak, metode ini mengambil hasil parsing terbaru melalui permintaan jaringan, mengembalikan hasil tersebut, dan memperbarui cache. Metode ini umumnya digunakan dalam skenario yang memerlukan akurasi parsing tinggi.

    • getIpv4ByHostFromCache(String hostName, boolean isAllowExp) mengambil array catatan IPv4 yang sesuai dengan hostName dari cache. Metode ini menentukan apakah akan mengembalikan catatan DNS kedaluwarsa dari cache berdasarkan nilai parameter isAllowExp. Kami merekomendasikan menggunakan metode ini bersama metode preload saat startup aplikasi untuk memastikan catatan DNS terbaru dicache saat aplikasi dimulai.

      Deskripsi: Jika isAllowExp bernilai true, metode ini mengembalikan catatan lama meskipun cache telah kedaluwarsa (atau null jika cache kosong) dan memperbarui cache secara asinkron. Jika bernilai false, metode ini mengembalikan null ketika cache kedaluwarsa atau kosong dan memperbarui cache secara asinkron.

    Pola yang direkomendasikan:

    String[] IPArray = mDNSResolver.getIpv4ByHostFromCache(hostname,true);
            if (IPArray == null || IPArray.length == 0){
                IPArray = mDNSResolver.getIPsV4ByHost(hostname);
            }

5. Aktifkan atau nonaktifkan caching

DNSResolver.setEnableCache(true); // Cache diaktifkan secara default.

Atur ke true untuk mengaktifkan caching atau false untuk menonaktifkannya.

6. Aktifkan atau nonaktifkan pengujian kecepatan IP

DNSResolver.setEnableSpeedTest(false); // Pengujian kecepatan IP dinonaktifkan secara default.

Atur ke true untuk mengaktifkan pengujian kecepatan IP atau false untuk menonaktifkannya.

7. Aktifkan atau nonaktifkan caching nama domain berbasis ISP

DNSResolver.setIspEnable(true);//Mengaktifkan caching nama domain berbasis ISP secara default.

Saat diaktifkan, setiap lingkungan jaringan (ISP) mempertahankan cache-nya sendiri. Saat dinonaktifkan, semua lingkungan jaringan berbagi satu cache.

8. Tetapkan TTL maksimum untuk cache negatif

DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);// Tetapkan TTL maksimum untuk cache negatif, nilai default adalah 30 detik

Cache negatif menyimpan respons untuk nama domain yang tidak memiliki alamat IP yang dikonfigurasi. Tetapkan TTL maksimum untuk entri cache tidak valid ini.

9. Tetapkan TTL maksimum untuk cache

DNSResolver.setMaxTtlCache(MAX_TTL_CACHE);// Menetapkan TTL maksimum untuk cache. Nilai default adalah 3600 detik.

Tetapkan TTL maksimum untuk entri cache. Jika ditetapkan, entri cache tidak akan melebihi TTL ini. Nilai default adalah 3600 detik.

10. Tetapkan informasi subnet klien

DNSResolver.setEdnsSubnet("1.2.XX.XX/24");

Metode setEdnsSubnet mendukung fitur EDNS Client Subnet (ECS) (RFC 7871). Fitur ini meneruskan informasi subnet ke server DNS otoritatif untuk resolusi dan pengalihan lalu lintas yang lebih akurat. Masker yang lebih panjang memberikan informasi alamat yang lebih tepat. Masker yang lebih pendek meningkatkan privasi. Kami merekomendasikan /24.

Catatan

Parameter ini dirancang khusus untuk skenario di mana proxy DNS menggunakan DoH JSON API—yaitu, pengguna mengirim kueri DNS ke proxy DNS, dan proxy DNS meneruskan informasi subnet pengguna menggunakan parameter ini ke HTTPDNS, lalu ke server DNS otoritatif.

Contohnya, DNSResolver.setEdnsSubnet("1.2.XX.XX/24") menyebabkan server otoritatif menerima informasi awalan berdasarkan awalan 1.2.XX.XX/24 untuk membantu Anda memilih jalur DNS.

11. Tetapkan timeout resolusi nama domain

timeout menentukan periode timeout untuk resolusi nama domain. Periode timeout default adalah 3 detik. Anda dapat menyesuaikan periode timeout, dan kami merekomendasikan menyetelnya antara 2 hingga 5 detik.

DNSResolver.setTimeout(3);

12. Dapatkan SessionId untuk troubleshooting

Parameter sessionId dihasilkan saat aplikasi dimulai dan tetap tidak berubah sepanjang siklus hidup aplikasi. Semua permintaan resolusi HTTPDNS dalam siklus hidup aplikasi yang sama membawa sessionId yang sama, dan server mencatat parameter ini serta menghasilkan indeks. SessionId digunakan untuk melacak siklus hidup aplikasi dan memecahkan masalah dalam skenario aplikasi.

public static String getSessionId()

13. Logging Callback

Log yang dihasilkan oleh callback SDK.

HttpDnsLog.setLogger(new ILogger() {
  @Override
  public void log(String msg) {
      Log.d("HttpDnsLogger:", msg);
  }
});

Konfigurasi obfuscation

   -keep class com.alibaba.pdns.** {*;}

API Layanan

  /**
   * Pra-memuat nama domain berdasarkan lingkungan jaringan yang terdeteksi otomatis (IPv4-only, IPv6-only, atau dual-stack).
   * Di lingkungan jaringan dual-stack, hasil resolusi IPv4 dan IPv6 dipra-muat. Anda dapat memanggil metode ini selama inisialisasi SDK saat aplikasi dimulai.
   * Metode ini menyimpan hasil resolusi di cache untuk mengurangi latensi resolusi nama domain berikutnya.
   *
   * @param domains Nama domain yang akan dipra-muat.
   */
   public void preLoadDomains(final String[] domains)

    /**
     * Pra-memuat nama domain tertentu untuk resolusi IPv4 atau IPv6.
     * Anda dapat memanggil metode ini selama inisialisasi SDK saat aplikasi dimulai. Metode ini menyimpan hasil resolusi di cache untuk mengurangi latensi resolusi nama domain berikutnya.
     *
     * @param qType Tentukan apakah akan memuat nama domain untuk resolusi IPv4 atau IPv6.
     * @param domains Nama domain yang akan dipra-muat.
     */
    public void preLoadDomains(String qType, final String[] domains)
   /**
   * Mendapatkan data resolusi untuk nama domain berdasarkan lingkungan jaringan yang terdeteksi otomatis (IPv4-only, IPv6-only, atau dual-stack).
   * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
   * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
   *
   * @param host Nama domain yang ingin Anda selesaikan.
   * @return Array alamat IP optimal berdasarkan lingkungan jaringan saat ini.
   */
    public String[] getIpsByHost(String host)

/**
    * Mendapatkan array catatan IPv4 yang sesuai dengan hostname.
    * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
    * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
    *
    * @param hostName Hostname, seperti www.taobao.com.
    * @return Array alamat IPv4 yang sesuai dengan hostname.
    */
  public  String[] getIPsV4ByHost(String hostName) 

   /**
    * Mendapatkan array catatan IPv6 yang sesuai dengan hostname.
    * @param hostName Hostname, seperti www.taobao.com.
    * @return Array alamat IPv6 yang sesuai dengan hostname.
    */
  public String[] getIPsV6ByHost(String hostName) 

  

  /**
   * Mendapatkan array alamat IP untuk nama domain yang diselesaikan dari cache berdasarkan lingkungan jaringan yang terdeteksi otomatis (IPv4-only, IPv6-only, atau dual-stack).
   * Jika cache kosong, metode ini mengembalikan null dan memulai kueri asinkron. Hasil kueri kemudian disimpan di cache.
   * Jika hasil resolusi ada di cache dan Anda mengizinkan pengembalian hasil kedaluwarsa, alamat IP kedaluwarsa dikembalikan, dan cache diperbarui secara asinkron.
   * Jika Anda tidak mengizinkan pengembalian hasil kedaluwarsa dan hasil cache telah kedaluwarsa, metode ini mengembalikan null dan kemudian memperbarui cache secara asinkron.
   *
   * @param host Nama domain yang Anda kueri, seperti www.taobao.com.
   * @param isAllowExp Tentukan apakah akan mengembalikan hasil resolusi nama domain yang kedaluwarsa.
   * @return Array alamat IP untuk host yang diselesaikan dari cache.
   */
   public String[] getIpsByHostFromCache(String host, boolean isAllowExp)
   
    /**
     * Mendapatkan array alamat IP tipe catatan IPv4 untuk nama domain yang diselesaikan dari cache.
     * Jika cache kosong, metode ini mengembalikan null dan memulai kueri asinkron. Hasil kueri kemudian disimpan di cache.
     * Jika hasil resolusi ada di cache dan Anda mengizinkan pengembalian hasil kedaluwarsa, alamat IP kedaluwarsa dikembalikan, dan cache diperbarui secara asinkron.
     * Jika Anda tidak mengizinkan pengembalian hasil kedaluwarsa dan hasil cache telah kedaluwarsa, metode ini mengembalikan null dan kemudian memperbarui cache secara asinkron.
     *
     * @param host Nama domain yang Anda kueri, seperti www.taobao.com.
     * @param isAllowExp Tentukan apakah akan mengembalikan hasil resolusi nama domain yang kedaluwarsa.
     * @return Mendapatkan array alamat IP tipe catatan IPv4 dari cache setelah field host diselesaikan.
     */
    private String[] getIpv4ByHostFromCache(String host , boolean isAllowExp)

    /**
     * Mendapatkan array alamat IP tipe catatan IPv6 untuk nama domain yang diselesaikan dari cache.
     * Jika cache kosong, metode ini mengembalikan null dan memulai kueri asinkron. Hasil kueri kemudian disimpan di cache.
     * Jika hasil resolusi ada di cache dan Anda mengizinkan pengembalian hasil kedaluwarsa, alamat IP kedaluwarsa dikembalikan, dan cache diperbarui secara asinkron.
     * Jika Anda tidak mengizinkan pengembalian hasil kedaluwarsa dan hasil cache telah kedaluwarsa, metode ini mengembalikan null dan kemudian memperbarui cache secara asinkron.
     *
     * @param host Nama domain yang Anda kueri, seperti www.taobao.com.
     * @param isAllowExp Tentukan apakah akan mengembalikan hasil resolusi nama domain yang kedaluwarsa.
     * @return Mendapatkan array alamat IP tipe catatan IPv6 dari cache setelah field host diselesaikan.
     */
    private String[] getIpv6ByHostFromCache(String host , boolean isAllowExp)

  /**
  * Mendapatkan array objek DomainInfo dalam catatan IPv4 yang sesuai dengan URL.
  * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
  * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
  *
  * @param url URL, seperti http://www.taobao.com.
  * @return Mendapatkan array objek DomainInfo dalam catatan IPv4 yang sesuai dengan URL.
  */
  public DomainInfo[] getIPsV4DInfoByUrl(String url) 

  Catatan: URL dalam objek DomainInfo adalah URL di mana field host secara otomatis diganti dengan alamat IP tertentu. Anda tidak perlu mengganti field host dalam URL secara manual.

  /**
   * Mendapatkan array objek DomainInfo dalam catatan IPv6 yang sesuai dengan URL.
   * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
   * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
   * 
   * @param url URL, seperti http://m.taobao.com.
   * @return Mendapatkan array objek DomainInfo dalam catatan IPv6 yang sesuai dengan URL.
   */
   public DomainInfo[] getIPsV6DInfoByUrl(String url) 

  /**
    * Mendapatkan objek DomainInfo dalam catatan IPv4 yang sesuai dengan URL tertentu.
    * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
    * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
    *
    * @param url URL, seperti http://m.taobao.com.
    * @return Mendapatkan objek DomainInfo dalam catatan IPv4 yang sesuai dengan URL.
    */
    public DomainInfo getIPV4DInfoByUrl(String url) 


  /**
    * Mendapatkan objek DomainInfo dalam catatan IPv6 yang sesuai dengan URL tertentu.
    * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
    * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
    *
    * @param url URL, seperti http://www.taobao.com.
    * @return Mendapatkan objek DomainInfo dalam catatan IPv6 yang sesuai dengan URL.
    */
   public DomainInfo getIPV6DInfoByUrl(String url) 

   Catatan: Objek DomainInfo yang dikembalikan membungkus properti berikut.

  /**
   * ID auto-increment dari titik akhir.
    */
    public String id = null;

   /**
    * URL yang dapat digunakan langsung. Host dalam URL diganti dengan alamat IP.
    */
     public String url = null;

    /**
    * Nama layanan yang perlu disertakan dalam header permintaan HTTP.
    */
    public String host = "";

   /**
    * Body konten yang dikembalikan.
    */
   public String data = null;

   /**
    * Waktu permintaan dimulai.
    */
   public String startTime = null;

   /**
    * Waktu permintaan berakhir. Jika permintaan timeout, nilai ini null.
    */
   public String stopTime = null; 

   /**
   * Kode status server yang dikembalikan, seperti 200, 404, atau 500.
    */
   public String code = null;

  /**
    * Mendapatkan catatan IPv4 yang sesuai dengan hostname.
    * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
     * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
  
    * @param hostName Hostname, seperti www.taobao.com.
    * @return Alamat IPv4 acak dalam kumpulan alamat IPv4 yang sesuai dengan hostname dikembalikan. Jika pengujian kecepatan koneksi alamat IP diaktifkan, alamat IPv4 optimal dikembalikan.
    */
  public String getIPV4ByHost(String hostName) 

   /**
    * Mendapatkan catatan IPv6 yang sesuai dengan hostname.
    * Jika hasil resolusi ada di cache dan belum kedaluwarsa, hasil dari cache dikembalikan.
    * Jika cache kosong atau hasil cache telah kedaluwarsa, permintaan jaringan sinkron dikirim ke server untuk mendapatkan hasil resolusi rekursif. Hasil tersebut kemudian dikembalikan kepada Anda dan disimpan di cache.
  
    * @param hostName Hostname, seperti www.taobao.com.
    * @return Mendapatkan alamat IPv6 acak dalam kumpulan alamat IPv6 yang sesuai dengan hostname. Jika pengujian kecepatan koneksi alamat IP diaktifkan, alamat IPv6 optimal dikembalikan.
    */
   public String getIPV6ByHost(String hostName) 
      

    /**
     * Mendapatkan statistik permintaan HTTPDNS yang berhasil dan gagal.
     *
     * @return Mendapatkan string array JSON dari statistik resolusi untuk semua nama domain.
     */
    public String getRequestReportInfo()
    
     /**
     * Menetapkan cadangan cache untuk nama domain. Resolusi nama domain yang dikonfigurasi dipicu secara otomatis ketika 75% TTL telah berlalu. Hal ini memastikan bahwa resolusi nama domain yang dikonfigurasi selalu mengenai cache dan meningkatkan efisiensi resolusi SDK.
     * Kami menyarankan agar Anda tidak mengonfigurasi terlalu banyak nama domain untuk fitur ini. Batas saat ini adalah 10 nama domain. Fitur ini dikonfigurasi secara independen dari fitur pra-resolusi.
     *
     * @param persistentCacheDomains
     */
    public synchronized static void setKeepAliveDomains(String[] persistentCacheDomains) {
    
     /**
     * Membersihkan cache nama domain tertentu. Jika hostname null, cache semua nama domain dibersihkan.
     *
     * @param domains Array nama domain yang cache-nya ingin Anda bersihkan.
     */
    public void clearHostCache(String[] domains){

Contoh penggunaan API

URL: Titik akhir input, misalnya http://www.taobao.com.

 String hostname = "www.taobao.com";
 String url = "http://www.taobao.com";

1. Dapatkan data IP optimal untuk lingkungan jaringan saat ini

String[] ip = DNSResolver.getInstance().getIpsByHost(hostname); // Dapatkan alamat IP optimal dari resolusi nama domain untuk jaringan saat ini.

2. Pra-muat resolusi nama domain untuk lingkungan jaringan saat ini

DNSResolver.getInstance().preLoadDomains(domains); // Pra-resolusi nama domain. Ganti `domains` dengan nama domain yang ingin Anda selesaikan menggunakan Alibaba Cloud DNS.

3. Ambil resolusi nama domain dari cache untuk lingkungan jaringan saat ini

String[] ip = DNSResolver.getInstance().getIpsByHostFromCache(hostname,true);// Dapatkan data resolusi nama domain dari cache untuk lingkungan jaringan saat ini.

4. Dapatkan alamat IPv4

String IPV4 = DNSResolver.getInstance().getIPV4ByHost(hostname); // Dapatkan alamat IPv4 dari resolusi nama domain.

5. Dapatkan alamat IPv6

String IPV6 =  DNSResolver.getInstance().getIPV6ByHost(hostname); // Dapatkan alamat IPv6 dari resolusi nama domain.

6. Ambil alamat IPv4 yang telah diselesaikan dari cache

String[] IPV4 =  DNSResolver.getInstance().getIpv4ByHostFromCache(hostname , true); // Dapatkan alamat IPv4 yang telah diselesaikan dari cache.

7. Ambil alamat IPv6 yang telah diselesaikan dari cache

String[] IPV6 =  DNSResolver.getInstance().getIpv6ByHostFromCache(hostname , true); // Dapatkan alamat IPv6 yang telah diselesaikan dari cache.

8. Ambil objek DomainInfo berdasarkan URL

DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(url); // Dapatkan URL yang telah diganti.

9. Bersihkan cache resolusi untuk nama domain tertentu

DNSResolver.getInstance().clearHostCache(hostName); // Bersihkan cache untuk nama domain tertentu. Atur hostName ke null untuk membersihkan cache semua nama domain.

10. Ambil statistik permintaan Alibaba Cloud DNS yang berhasil dan gagal

String reportInfo = DNSResolver.getInstance().getRequestReportInfo(); // Dapatkan statistik tentang permintaan yang berhasil dan gagal.

Field dalam array string JSON statistik resolusi nama domain dijelaskan sebagai berikut:

 [
      {
         "avgRtt":"1",                         // Waktu rata-rata resolusi nama domain, dalam milidetik (ms)
         "degradeLocalDnsCount": 0,            // Jumlah kali menurun ke Local DNS
         "domainName":"www.example.com",       // Nama domain yang diselesaikan
         "hitDnsCacheCount": 1,                // Jumlah hit cache
         "httpabnormalCount": 0,               // Jumlah kueri rekursif yang gagal
         "isp": "China Mobile",                // Nama ISP
         "localDnsResolveErrCount": 0,         // Jumlah kegagalan resolusi Local DNS
         "maxRtt": 8.0,                        // Waktu maksimum resolusi nama domain, dalam milidetik (ms)
         "nonetworkCount": 0,                  // Jumlah kali tanpa konektivitas jaringan
         "permissionErrCount": 0,              // Jumlah kegagalan otentikasi pengguna
         "queryType": 1,                       // Tipe IP. 1 menunjukkan IPv4. 28 menunjukkan IPv6
         "recursiveReqCount": 1,               // Jumlah kueri rekursif
         "reqParameterErrCount": 0,            // Jumlah kesalahan format parameter permintaan
         "reqPathErrCount": 0,                 // Jumlah kesalahan URL
         "reqServerErrCount": 0,               // Jumlah kesalahan sisi server DNS
         "reqTimeoutCount": 0,                 // Jumlah kesalahan timeout layanan DNS
         "resolveSuccessCount": 1,             // Jumlah resolusi yang berhasil
         "timeoutCount": 0,                    // Jumlah kesalahan timeout jaringan
         "utfNetWorkErroNum": 0                // Jumlah kesalahan timeout pelaporan data
      }
         ......
 ]
Penting

Statistik untuk permintaan resolusi nama domain ke HTTPDNS diagregasi berdasarkan dimensi statistik lingkungan jaringan, nama domain, dan tipe permintaan.

Contoh

public class MainActivity extends AppCompatActivity {
   private Button button;
   private TextView tvInfo;
   private TextView tvResult;
   private String hostUrl = "http://www.taobao.com"; // Ganti ini dengan hostUrl yang ingin Anda selesaikan.
   private String hostName = "www.taobao.com"; // Ganti ini dengan hostName yang ingin Anda selesaikan.
   private static final String TAG = "PDnsDemo";
   private static ExecutorService pool = Executors.newSingleThreadExecutor();
   private static final String PDNS_RESULT = "pdns_result";
   private static final int SHOW_CONSOLE_TEXT = 10000;
   private Handler mHandler;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.demo_activity_main);
       init();
       initHandler();
   }
 private void init() {
       tvInfo = findViewById(R.id.tv_respons_info);
       tvResult = findViewById(R.id.tv_respons);
       button = findViewById(R.id.btn_onclik);
       button.setOnClickListener(new View.OnClickListener() {
           public void onClick(View view) {
               new Thread(new Runnable() {
                      @Override
                      public void  run() {
                      // Panggil metode getIPV4ByHost dari SDK HTTPDNS untuk mendapatkan alamat IP yang diselesaikan dari nama domain target.
                      String ip = DNSResolver.getInstance().getIPV4ByHost(hostName);
                      if(ip != null){
                         tvInfo.setText("The resolved IP for the domain is: "+ ip);
                      }
                      // Panggil metode getIPV4DInfoByUrl dari SDK HTTPDNS untuk mendapatkan objek DomainInfo. URL dalam objek ini adalah URL asli dengan host-nya diganti oleh alamat IP yang diselesaikan.
                      DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(hostUrl);
                      if (dinfo != null) {
                           showResponse(dinfo);
                      }
                   }
               }).start();
           }
       });
   }
   private void initHandler() {
       mHandler = new Handler() {
           @Override
           public void handleMessage(Message msg) {
               switch (msg.what)  {
                   case SHOW_CONSOLE_TEXT:
                       tvResult.setText(msg.getData().getString(PDNS_RESULT) + "\n");
                       break;
               }
           }
       };
   }
   private void showResponse(final DomainInfo dinfo) {
                // Kirim permintaan HTTP
               String requestUrl = dinfo.url;
               HttpURLConnection conn = null;
               try {
                   URL url = new URL(requestUrl);
                   conn = (HttpURLConnection) url.openConnection();
                   // Saat mengakses menggunakan alamat IP, Anda harus menyetel field host di header permintaan HTTP ke nama domain yang diselesaikan.
                   conn.setRequestProperty("Host", url.getHost()); // Setel field host di header permintaan HTTP.
                   DataInputStream dis = new DataInputStream(conn.getInputStream());
                   int len;
                   byte[] buff = new byte[4096];
                   StringBuilder response = new StringBuilder();
                   while ((len = dis.read(buff)) != -1) {
                       response.append(new String(buff, 0, len));
                   }
                   Log.d(TAG, "Response: " + response.toString());
                   dis.close();
                   sendMessage(response.toString());
               } catch (IOException e) {
                   e.printStackTrace();
               } finally {
                   if (conn != null) {
                       conn.disconnect();
                   }
               }
           }
   private void sendMessage(String message) {
       if (mHandler != null) {
               Message msg = mHandler.obtainMessage();
               Bundle bundle = new Bundle();
               bundle.putString(PDNS_RESULT, message);
               msg.setData(bundle);
               msg.what = SHOW_CONSOLE_TEXT;
               mHandler.sendMessage(msg);
       }
   }
}

public class DnsCacheApplication extends Application {
    
    private String Account ID = "your Account ID"; // Tetapkan Account ID Anda untuk integrasi SDK di konsol.
    private String AccessKey ID = "your AccessKey ID"; // Tetapkan AccessKey ID Anda untuk integrasi SDK di konsol.
    private String AccessKey Secret = "your AccessKey secret"; // Tetapkan AccessKey secret Anda untuk integrasi SDK di konsol.

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this, Account ID, AccessKey ID, AccessKey Secret); // Konfigurasikan Account ID, AccessKey ID, dan AccessKey secret untuk integrasi SDK di konsol.
       DNSResolver.setKeepAliveDomains(new String[]{"domain-name-1", "domain-name-2", ...}); // Konfigurasikan nama domain untuk cadangan cache. Nama domain ini secara otomatis diselesaikan pada 75% TTL-nya untuk memastikan hit cache selama resolusi nama domain.
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4, new String[]{"domain-name-to-preload-1", "domain-name-to-preload-2", ...}); // Pra-resolusi nama domain IPv4. Ganti nama domain yang dipra-muat dengan nama domain yang ingin Anda selesaikan menggunakan Alibaba Cloud DNS.
    }
}

Praktik terbaik untuk resolusi nama domain

Pra-resolusi + Izinkan balasan kedaluwarsa = Performa terbaik

Dalam skenario jaringan berkinerja tinggi, menggabungkan pra-resolusi dengan mengizinkan balasan kedaluwarsa secara signifikan meningkatkan kecepatan resolusi DNS—bahkan mencapai resolusi tanpa latensi.

BerKat cache bawaan SDK, setelah pra-resolusi, permintaan berikutnya untuk nama domain yang sama langsung mengenai cache. Hal ini menghindari round trip jaringan dan sangat meningkatkan pengalaman pengguna.

1. Pra-resolusi

Aktifkan caching dan pra-resolusi nama domain kritis (disarankan saat startup aplikasi).

Di kelas Application, selesaikan nama domain yang digunakan dalam logika bisnis Anda terlebih dahulu di metode onCreate(), dan cache hasilnya di memori lokal.

1. Untuk lingkungan IPv4-only

// ******** Untuk skenario yang hanya mendukung IPv4 *******
public class DnsCacheApplication extends Application{
    private String Account ID = "your Account ID"; // Tetapkan Account ID Anda untuk integrasi SDK di konsol
    private String AccessKey ID = "your AccessKey ID"; // Tetapkan AccessKey ID Anda untuk integrasi SDK di konsol
    private String AccessKey Secret = "your AccessKey secret "; // Tetapkan AccessKey secret Anda untuk integrasi SDK di konsol

    @Override
    public void onCreate() {
       super.onCreate();
       DNSResolver.Init(this,Account ID,AccessKey ID,AccessKey Secret); // Tetapkan Account ID, AccessKey ID, dan AccessKey secret Anda untuk integrasi SDK di konsol
       DNSResolver.setEnableCache(true); // Aktifkan caching. Nilai default: true
       // Tipe catatan IPv4 untuk pra-resolusi    
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"example-domain-1.com","example-domain-2.com",...}); // Pra-resolusi nama domain tipe IPv4 tertentu. Ganti nama domain contoh dengan nama domain yang ingin Anda selesaikan menggunakan Alibaba Cloud DNS.
    }
}

2. Untuk lingkungan yang mendukung IPv6

//********Ini berlaku untuk skenario yang memerlukan dukungan IPv6.*******
public class DnsCacheApplication extends Application{
    private String accountID = "your_account_id"; // Tetapkan Account ID untuk mengakses SDK dari konsol.
    private String accessKeyID = "your_accesskey_id"; // Tetapkan AccessKey ID untuk mengakses SDK dari konsol.
    private String accessKeySecret = "your_accesskey_secret"; // Tetapkan AccessKey secret untuk mengakses SDK dari konsol.

    @Override
    public void onCreate() {
       super.onCreate();
       // Tetapkan Account ID, AccessKey ID, dan AccessKey secret untuk mengakses SDK dari konsol.
       DNSResolver.Init(this, accountID, accessKeyID, accessKeySecret);
       // Tentukan apakah akan mengaktifkan caching. Fitur ini diaktifkan secara default.
       DNSResolver.setEnableCache(true);
       // Tentukan apakah akan mengaktifkan resolusi nama domain melalui jaringan IPv6. Fitur ini dinonaktifkan secara default.
       DNSResolver.setEnableIPv6(true);  
       // Tentukan apakah akan mengaktifkan pengujian kecepatan IP. Fitur ini dinonaktifkan secara default.
       DNSResolver.setEnableSpeedTest(true); 
       // Pra-resolusi nama domain menjadi alamat IPv4 dan IPv6.
       // Pra-resolusi nama domain tipe IPv4 dan IPv6 tertentu. Ganti nama domain contoh dengan nama domain yang ingin Anda selesaikan menggunakan Alibaba Cloud DNS.
       DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4_IPV6,new String[]{"your_domain_to_preload_1","your_domain_to_preload_2",...});
    }
}

2. Izinkan balasan kedaluwarsa

Gunakan hasil cache terlebih dahulu (izinkan IP kedaluwarsa). Sebelum mengirim permintaan jaringan, ambil alamat IP dari cache dan izinkan penggunaan entri cache kedaluwarsa namun masih dapat digunakan. Hal ini memberikan hasil segera—bahkan setelah masa berlaku TTL berakhir—asalkan entri cache tersebut ada. Hal ini mencapai waktu tunggu nol.

1. Untuk lingkungan IPv4-only

    //********Berlaku untuk skenario yang hanya mendukung IPv4*******
    @Override
    public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
        // Utamakan pengambilan alamat IP dari cache (parameter kedua diatur ke true untuk mengizinkan pengembalian catatan kedaluwarsa namun aktif)
        String[] IPArray = mDNSResolver.getIpv4ByHostFromCache(hostname,true);
        if (IPArray == null || IPArray.length == 0){
            // Cache miss, picu resolusi asinkron
            IPArray = mDNSResolver.getIPsV4ByHost(hostname);
        }
        if (IPArray != null && IPArray.length > 0) {
            List<InetAddress> inetAddresses = new ArrayList<>();
            InetAddress address;
            for (String ip : IPArray) {
                address = InetAddress.getByName(ip);
                inetAddresses.add(address);
            }
            if (!inetAddresses.isEmpty()) {
                return inetAddresses;
            }
        }
        return okhttp3.Dns.SYSTEM.lookup(hostname);
    }

2. Untuk lingkungan yang mendukung IPv6

    //********Berlaku untuk skenario yang memerlukan dukungan IPv6*******
    @Override
    public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
        // Pertama ambil alamat IP dari cache (parameter kedua diatur ke true untuk mengizinkan pengembalian catatan kedaluwarsa namun aktif)
        String[] IPArray = mDNSResolver.getIpsByHostFromCache(hostname,true);
        if (IPArray == null || IPArray.length == 0){
            // Cache miss: picu resolusi asinkron
            IPArray = mDNSResolver.getIpsByHost(hostname);
        }
        if (IPArray != null && IPArray.length > 0) {
            List<InetAddress> inetAddresses = new ArrayList<>();
            InetAddress address;
            for (String ip : IPArray) {
                address = InetAddress.getByName(ip);
                inetAddresses.add(address);
            }
            if (!inetAddresses.isEmpty()) {
                return inetAddresses;
            }
        }
        return okhttp3.Dns.SYSTEM.lookup(hostname);
    }

Catatan penggunaan

  1. Setelah mendapatkan alamat IP nama domain melalui HTTPDNS, klien dapat menggunakan alamat IP ini untuk mengirim permintaan bisnis, dan field Host di header permintaan HTTP harus diatur ke nama domain asli.

  2. Untuk memastikan operasi bisnis berjalan normal, ketika SDK HTTPDNS mengembalikan alamat IP kosong untuk resolusi nama domain, developer aplikasi harus menggunakan URL permintaan berbasis domain asli untuk permintaan fallback. Contoh kode berikut menunjukkan hal ini:

    String ip = DNSResolver.getInstance().getIPV4ByHost("domain name");
    if (ip != null) {
    	// Ganti host di URL dengan alamat IP untuk membuat permintaan API.
    }else {
    	// Buat permintaan fallback menggunakan URL permintaan dengan nama domain asli.
    }
  3. Untuk membantu Anda memulai dengan SDK HTTPDNS lebih cepat, kami menyediakan program demo yang dapat Anda unduh secara lokal untuk referensi. Klik di sini untuk mengunduh program demo.

  4. Setelah menyelesaikan integrasi SDK, periksa bagian Analisis Trafik di konsol untuk memverifikasi keberhasilan integrasi. Jika tidak ada trafik yang dihasilkan, verifikasi bahwa parameter Account ID, AccessKey ID, dan AccessKey Secret dikonfigurasi dengan benar.

DNS On-premises

Mulai v2.3.0, SDK Android HTTPDNS mendukung penyebaran DNS on-premises.

DNS on-premises cocok untuk skenario dengan persyaratan kepatuhan ketat atau kebijakan resolusi kustom—seperti keuangan, pemerintahan, dan perusahaan internet besar. SDK mendukung empat mode penyebaran: DNS cloud publik saja, DNS on-premises saja, hybrid aktif-standby (DNS cloud publik + DNS on-premises sebagai fallback timbal balik), dan adaptasi fleksibel terhadap arsitektur bisnis yang berbeda.

Kemampuan inti

  • Dukungan penyebaran on-premises: Konfigurasikan titik akhir DNS on-premises menggunakan alamat IPv4/IPv6 atau nama domain host.

  • Mekanisme otentikasi dua arah: Menggunakan accessKeyId dan accessKeySecret spesifik pelanggan untuk menandatangani permintaan, memastikan komunikasi aman.

  • Pemutusan sirkuit dan pemeriksaan kesehatan: Ketika node DNS yang dikelola sendiri gagal berturut-turut tiga kali atau lebih, node tersebut secara otomatis diputus sirkuitnya. Selanjutnya, ketersediaannya diperiksa setiap menit menggunakan healthCheckDomain yang ditentukan. Setelah pulih, node tersebut diaktifkan kembali secara otomatis.

  • Kontrol validasi sertifikat: Aktifkan atau nonaktifkan validasi sertifikat TLS (sangat direkomendasikan untuk lingkungan produksi).

  • Fallback cerdas: Ketika DNS primer (DNS cloud publik atau DNS on-premises) gagal melebihi ambang batas, secara otomatis beralih ke DNS standby untuk memastikan ketersediaan tinggi.

  • Kompatibilitas API mulus: Baik menggunakan DNS cloud publik maupun DNS on-premises, panggilan API resolusi lapisan atas tetap identik—tidak diperlukan perubahan logika bisnis.

Rincian konfigurasi

1. Gunakan hanya DNS cloud publik

Untuk pengguna SaaS standar yang tidak menyebar DNS on-premises.

DNSResolver.Init(this, accountID,accessKeyId,accessKeySecret);

2. Gunakan hanya DNS on-premises (penyebaran on-premises)

Untuk pelanggan yang sepenuhnya bergantung pada DNS on-premises.

DNSResolver.InitFusionDNS(this,new String[]{"1.1.X.X","2.2.X.X"},null,null,"443", "check.example.com", "your_fusion_ak", "your_fusion_sk");
// Opsional: Nonaktifkan validasi sertifikat (hanya untuk lingkungan staging)
// DNSResolver.setEnableCertificateValidation(false);

3. DNS cloud publik sebagai primer, DNS on-premises sebagai standby

Beralih ke DNS on-premises ketika DNS HTTP publik Alibaba Cloud primer gagal.

// Primer: DNS cloud publik
DNSResolver.Init(this, accountID,accessKeyId,accessKeySecret);
    
// Sekunder: DNS on-premises
DNSResolver.InitFusionDNS(this,new String[]{"1.1.X.X","2.2.X.X"},null,null,"443", "check.example.com", "your_fusion_ak", "your_fusion_sk");
// Opsional: nonaktifkan validasi sertifikat (hanya untuk lingkungan staging)
// DNSResolver.setEnableCertificateValidation(false);

4. DNS on-premises sebagai primer, DNS cloud publik sebagai standby

Beralih ke DNS publik Alibaba Cloud ketika DNS on-premises primer gagal.

// Primer: DNS on-premises
DNSResolver.InitFusionDNS(this,new String[]{"1.1.X.X","2.2.X.X"},null,null,"443", "check.example.com", "your_fusion_ak", "your_fusion_sk");
// Opsional: Nonaktifkan validasi sertifikat (hanya untuk lingkungan staging).
// DNSResolver.setEnableCertificateValidation(false);

// Cadangan: DNS cloud publik
DNSResolver.Init(this, accountID,accessKeyId,accessKeySecret);

API layanan baru

Untuk mendukung penyebaran DNS on-premises dan pemulihan bencana ketersediaan tinggi, SDK menambahkan tiga API inti untuk mengonfigurasi DNS on-premises, mengontrol kebijakan keamanan, dan mengaktifkan failover otomatis primer-standby.

1. Konfigurasikan titik akhir DNS on-premises dan otentikasi

    /** Mengonfigurasi server DNS yang dikelola sendiri untuk penyebaran pribadi. Jika Anda hanya menggunakan DNS publik, Anda tidak perlu memanggil metode ini.
     *
     * Menetapkan alamat dan informasi otentikasi untuk server DNS yang dikelola sendiri.
     * Pelanggan meneruskan alamat server DNS pribadi dan kredensial otentikasi melalui antarmuka ini.
     * SDK menggunakan informasi ini untuk membuat permintaan.
     * @param ctx Context
     * @param serverIpv4Arr Array alamat IPv4 (dapat null)
     * @param serverIpv6Arr Array alamat IPv6 (dapat null)
     * @param serverHostArr Array nama domain host (dapat null)
     * @param port Port layanan (misalnya, "443". Jika null, nilai default "443" digunakan)
     * @param healthCheckDomain Nama domain yang digunakan untuk pemeriksaan kesehatan setelah pemutusan sirkuit. Ketika layanan resolusi DNS gagal berturut-turut lebih dari tiga kali, pemutusan sirkuit dipicu, dan alamat IP layanan tersebut memasuki status healthCheck (permintaan berikutnya tidak akan menggunakan layanan ini). Timer berjalan setiap menit untuk memanggil API resolusi DNS menggunakan healthCheckDomain ini untuk memeriksa apakah layanan resolusi DNS tersedia. Jika pemeriksaan berhasil, layanan kembali ke status alive (permintaan berikutnya dapat menggunakan layanan ini)
     * @param accessKeyId ID kunci akses pribadi pelanggan (digunakan untuk otentikasi)
     * @param accessKeySecret Rahasia kunci akses pribadi pelanggan (digunakan untuk otentikasi)
     */
    public static void InitFusionDNS(Context ctx,String[] serverIpv4Arr, String[] serverIpv6Arr, String[] serverHostArr, String port, String healthCheckDomain, String accessKeyId, String accessKeySecret)

2. Kontrol validasi sertifikat TLS untuk DNS on-premises

    /**Untuk DNS on-premises yang digunakan dalam penyebaran pribadi. Anda tidak perlu mengonfigurasi metode ini jika hanya menggunakan DNS publik.
     *
     * Menentukan apakah akan mengaktifkan validasi sertifikat untuk DNS on-premises (default: true). Jika server tidak dikonfigurasi dengan sertifikat nama domain atau sertifikat IP, Anda dapat menyetel parameter ini ke false untuk pengujian. Namun, ketika Anda menyebar ke lingkungan produksi, kami merekomendasikan agar Anda menyetelnya ke true. Jika tidak, risiko keamanan mungkin timbul.
     * @param enable Setel ke true untuk mengaktifkan validasi sertifikat (default: true). Setel ke false untuk menonaktifkannya.
     */
    public static void setEnableCertificateValidation(boolean enable)

3. Tetapkan ambang batas failover otomatis untuk DNS primer-standby

    /**Ketika DNS cloud publik dan DNS on-premises dikonfigurasi, tentukan jumlah kali kegagalan resolusi DNS pada DNS primer sebelum secara otomatis menurunkan spesifikasi ke DNS sekunder sebagai fallback. Jika hanya satu tipe DNS yang dikonfigurasi, Anda tidak perlu mengonfigurasi metode ini.
     *
     * Tentukan jumlah kali kegagalan resolusi DNS pada DNS primer sebelum secara otomatis menurunkan spesifikasi ke DNS sekunder sebagai fallback. Jika hanya satu tipe DNS yang dikonfigurasi, Anda tidak perlu mengonfigurasi metode ini.
     * @param fallbackThreshold Jumlah kegagalan (default adalah 4 ketika DNS cloud publik adalah primer, atau 2 ketika DNS on-premises adalah primer).
     * Nilai valid dari 0 hingga 4. Menyetel 0 berarti downgrade segera. Nilai maksimum adalah 4.
     */
     public static void setFallbackThreshold(int fallbackThreshold)