All Products
Search
Document Center

HTTPDNS:Praktik terbaik untuk HTTPDNS dan gRPC di Android

Last Updated:Dec 04, 2025

Dokumen proses integrasi Android SDK menjelaskan proses lengkap impor dan konfigurasi Android SDK, penguraian alamat IP, penerapan SDK ke library jaringan, serta verifikasi integrasi. Topik ini menjelaskan prosedur spesifik untuk menggunakan HTTPDNS bersama gRPC.

1. Latar Belakang

gRPC adalah framework Remote Procedure Call (RPC) open-source berkinerja tinggi dari Google yang berbasis protokol HTTP/2 dan banyak digunakan dalam arsitektur mikroservis. Secara default, gRPC menggunakan DNS sistem untuk resolusi nama domain. Namun, gRPC juga menyediakan mekanisme ekstensi NameResolver yang memungkinkan developer menyesuaikan logika resolusi.
Di Android, jika aplikasi Anda menggunakan gRPC, Anda dapat mengimplementasikan NameResolver kustom untuk mengintegrasikan HTTPDNS ke dalam gRPC, sehingga menggantikan DNS sistem dalam proses resolusi nama domain.

Catatan: Solusi ini berlaku untuk client gRPC yang menggunakan grpc-okhttp sebagai lapisan transport, yang merupakan metode yang direkomendasikan untuk Android.

2. Cara Kerja

Alur resolusi nama domain gRPC adalah sebagai berikut:

ManagedChannel
    ↓
NameResolver (custom endpoint)
    ↓
LoadBalancer
    ↓
Transport (grpc-okhttp)
    ↓
TCP connection

Dengan membuat NameResolver kustom, Anda dapat mengintegrasikan HTTPDNS pada tahap resolusi nama domain. NameResolver kustom tersebut mengembalikan daftar alamat IP yang telah diselesaikan kepada gRPC, lalu LoadBalancer gRPC menangani load balancing dan failover.

3. Langkah Integrasi

3.1 Tambahkan dependensi

Tambahkan dependensi gRPC ke file build.gradle Anda:

dependencies {
    // EMAS HTTPDNS
    implementation 'com.aliyun.ams:alicloud-android-httpdns:x.x.x'
    // gRPC Android
    implementation 'io.grpc:grpc-okhttp:x.x.x'
    implementation 'io.grpc:grpc-stub:x.x.x'
    implementation 'io.grpc:grpc-protobuf-lite:x.x.x'
}

3.2 Inisialisasi HTTPDNS

Inisialisasi layanan HTTPDNS di kelas Application Anda:

public class MyApplication extends Application {
    @Overridepublic void onCreate() {
        super.onCreate();
        
        // Initialize HTTPDNS
        InitConfig config = new InitConfig.Builder()
                .setContext(this)
                .setSecretKey("your_secret_key")  // Optional
                .setEnableCacheIp(true, 24 * 60 * 60 * 1000)  // Enable cache
                .setEnableExpiredIp(true)  // Allow use of expired IPs
                .setTimeoutMillis(2000)
                .build();
        
        HttpDns.init("your_account_id", config);
    }
}

3.3 Implementasikan NameResolver kustom

Buat kelas EmasHttpDnsNameResolver:

import io.grpc.EquivalentAddressGroup;
import io.grpc.NameResolver;
import io.grpc.Status;
import com.alibaba.sdk.android.httpdns.HttpDns;
import com.alibaba.sdk.android.httpdns.HttpDnsService;
import com.alibaba.sdk.android.httpdns.HTTPDNSResult;
import com.alibaba.sdk.android.httpdns.RequestIpType;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;

public class EmasHttpDnsNameResolver extends NameResolver {

    private final String host;
    private final int port;
    private Listener2 listener;

    public EmasHttpDnsNameResolver(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Overridepublic String getServiceAuthority() {
        return host;
    }

    @Overridepublic void start(Listener2 listener) {
        this.listener = listener;
        resolve();
    }

    @Overridepublic void refresh() {
        resolve();
    }

    private void resolve() {
        List<EquivalentAddressGroup> addressGroups = new ArrayList<>();

        try {
            // Call HTTPDNS to resolve the domain name
            HttpDnsService httpDnsService = HttpDns.getService("your_account_id");
            HTTPDNSResult result = httpDnsService.getHttpDnsResultForHostSyncNonBlocking(
                host, 
                RequestIpType.auto
            );

            // If HTTPDNS returns null, fall back to the system DNS
            if (result == null || 
                (result.getIps() == null || result.getIps().length == 0) &&
                (result.getIpv6s() == null || result.getIpv6s().length == 0)) {
                
                InetAddress[] systemAddrs = InetAddress.getAllByName(host);
                for (InetAddress addr : systemAddrs) {
                    addressGroups.add(new EquivalentAddressGroup(
                        new InetSocketAddress(addr, port)
                    ));
                }
            } else {
                // Add IPv4 addresses
                if (result.getIps() != null) {
                    for (String ip : result.getIps()) {
                        addressGroups.add(new EquivalentAddressGroup(
                            new InetSocketAddress(ip, port)
                        ));
                    }
                }
                
                // Add IPv6 addresses
                if (result.getIpv6s() != null) {
                    for (String ip : result.getIpv6s()) {
                        addressGroups.add(new EquivalentAddressGroup(
                            new InetSocketAddress(ip, port)
                        ));
                    }
                }
            }

            // Return the resolution result
            ResolutionResult resolutionResult = ResolutionResult.newBuilder()
                    .setAddresses(addressGroups)
                    .build();

            listener.onResult(resolutionResult);

        } catch (Exception e) {
            listener.onError(Status.UNAVAILABLE.withDescription(
                "HTTPDNS resolve failed: " + e.getMessage()
            ));
        }
    }

    @Overridepublic void shutdown() {
        // Clean up resources
    }
}

3.4 Implementasikan NameResolverProvider

Buat kelas EmasHttpDnsResolverProvider:

import io.grpc.NameResolver;
import io.grpc.NameResolverProvider;
import java.net.URI;

public class EmasHttpDnsResolverProvider extends NameResolverProvider {

    private static final String SCHEME = "emashttpdns";

    @Overrideprotected boolean isAvailable() {
        return true;
    }

    @Overrideprotected int priority() {
        return 5;
    }

    @Overridepublic NameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
        if (!SCHEME.equals(targetUri.getScheme())) {
            return null;
        }

        String host = targetUri.getHost();
        int port = targetUri.getPort() == -1 ? 443 : targetUri.getPort();

        return new EmasHttpDnsNameResolver(host, port);
    }

    @Overridepublic String getDefaultScheme() {
        return SCHEME;
    }
}

3.5 Daftarkan NameResolver

Daftarkan NameResolver kustom di kelas Application Anda:

public class MyApplication extends Application {
    @Overridepublic void onCreate() {
        super.onCreate();
        
        // Initialize HTTPDNS (see step 3.2)
        // ...
        
        // Register the custom NameResolver
        NameResolverRegistry.getDefaultRegistry()
                .register(new EmasHttpDnsResolverProvider());
    }
}

3.6 Gunakan client gRPC

Saat membuat channel gRPC, gunakan skema kustom:

// Create the channel
ManagedChannel channel = OkHttpChannelBuilder
        .forTarget("emashttpdns://your-grpc-server.com:443")
        .overrideAuthority("your-grpc-server.com")  // Important: This ensures correct TLS SNI
        .useTransportSecurity()  // Enable TLS
        .build();

// Create the stub and make the call
YourServiceGrpc.YourServiceBlockingStub stub = 
    YourServiceGrpc.newBlockingStub(channel);

YourResponse response = stub.yourMethod(request);

4. Verifikasi Integrasi

Setelah integrasi selesai, Anda dapat memverifikasi keberhasilannya menggunakan metode seperti hijacking impersonation atau pengujian fault injection. Untuk informasi lebih lanjut, lihat dokumen Verifikasi Integrasi Library Jaringan yang Berhasil.

5. Ringkasan

Dengan mengimplementasikan antarmuka NameResolver gRPC, Anda dapat mengintegrasikan HTTPDNS ke dalam client gRPC Anda. Pendekatan ini memberikan keuntungan berikut:

  • Implementasi sederhana: Anda hanya perlu mengimplementasikan antarmuka NameResolver untuk mengintegrasikan layanan HTTPDNS.

  • Versatilitas tinggi: Metode ini berlaku untuk berbagai skenario gRPC dan kompatibel dengan mekanisme keamanan seperti validasi sertifikat dan Server Name Indication (SNI).

  • Ketersediaan tinggi: Mendukung load balancing otomatis dan failover di antara beberapa alamat IP. Jika resolusi HTTPDNS gagal, sistem secara otomatis kembali menggunakan DNS sistem.

  • Optimalisasi kinerja: Membantu mencegah DNS hijacking serta meningkatkan kecepatan dan tingkat keberhasilan resolusi.