Intégrez le SDK Android HTTPDNS à votre application pour une résolution de domaine fiable avec mise en cache intégrée.
Présentation
Le SDK Android est un wrapper Java pour l'API JSON DoH HTTPDNS. Il fournit des interfaces Java permettant aux applications Android de résoudre les noms de domaine et inclut un cache local efficace utilisant les politiques TTL (Time-to-Live) et LRU (Least Recently Used). Vous pouvez intégrer HTTPDNS dans votre application Android pour corriger les erreurs de résolution de domaine et activer une planification précise et économique.
Principaux avantages :
-
Simplicité d'utilisation
Un minimum de code est nécessaire pour accéder au service HTTPDNS.
-
Latence nulle
Le cache LRU stocke localement les adresses IP résolues et actualise proactivement les entrées avant l'expiration du TTL, permettant ainsi une résolution sans latence.
Téléchargez le projet exemple alidns_android_demo pour disposer d'une référence d'implémentation fonctionnelle.
Intégration du SDK
Ajout du SDK
Gradle et Maven
Ajoutez le code suivant à votre fichier build.gradle :
allprojects {
repositories {
maven {
url 'https://maven.aliyun.com/repository/public/'
}
mavenLocal()
mavenCentral()
}
}
Ajoutez les informations de dépendance :
dependencies {
implementation 'com.alibaba.pdns:alidns-android-sdk:2.3.3'
implementation 'com.google.code.gson:gson:2.8.5'
}
Fichier AAR
Téléchargez le SDK depuis la page Télécharger le SDK, puis ajoutez le package alidns_android_sdk.aar au répertoire libs de votre projet.
Initialisation du SDK
Initialisez le SDK aussi tôt que possible dans le cycle de vie de votre application afin d'éviter les échecs de résolution.
Récupérez votre ID de compte depuis la console et créez une clé pour obtenir votre AccessKey ID et votre AccessKey Secret. Initialisez ensuite le SDK comme indiqué dans cet exemple de classe Application :
public class DnsCacheApplication extends Application{
private String accountId = "Your Account ID"; // Set your Account ID from the console.
private String accessKeyId = "Your AccessKey ID"; // Set your AccessKey ID from the console.
private String accessKeySecret = "Your AccessKey Secret"; // Set your AccessKey Secret from the console.
@Override
public void onCreate() {
super.onCreate();
// Set the Account ID, AccessKey ID, and AccessKey Secret for SDK access.
DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret);
// Note: If you configure domains for keep-alive, resolution is automatically triggered when 75% of the TTL elapses.
// This ensures that resolution for these domains always hits the cache. However, if you use a CDN,
// the TTL can be short, leading to frequent requests and increased costs. Use this method with caution.
DNSResolver.setKeepAliveDomains(new String[]{"your-domain-to-keep-alive-1","your-domain-to-keep-alive-2",...});
// Perform pre-resolution for specified domains to get IPv4 addresses. Replace the placeholder domains with the ones you want to resolve.
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"your-domain-to-preload-1","your-domain-to-preload-2",...});
}
}
DNSResolver est la classe principale du SDK HTTPDNS. Elle encapsule l'API JSON DoH HTTPDNS pour résoudre les noms de domaine en adresses IP. Initialisez le SDK HTTPDNS dans votre sous-classe Application.
Déclarez les permissions suivantes dans le fichier AndroidManifest.xml :
<!--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"/>
Authentification du SDK
À partir de la version 2.0, le SDK requiert une authentification pour prévenir toute utilisation non autorisée. Pour activer HTTPDNS, créez une clé dans la console afin d'obtenir un AccessKey ID et un AccessKey Secret. Vous devez définir les paramètres d'authentification lors de l'initialisation du SDK. HTTPDNS rejette les requêtes non authentifiées, ce qui entraîne un échec de la résolution et impacte vos services.HTTPDNS
Vous pouvez définir les paramètres d'authentification comme suit :
DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret);
Pour éviter que votre ID de compte, AccessKey ID, AccessKey Secret ou d'autres données d'exécution ne soient exposés dans les journaux, désactivez la journalisation de débogage du SDK dans votre version de production.
L'intégration du SDK nécessite de définir l'ID de compte, l'AccessKey ID et l'AccessKey Secret dans votre code. Ces paramètres sont liés à la comptabilisation et à la facturation. Pour empêcher qu'un décompilation malveillante n'expose vos identifiants, activez l'obfuscation du code et le renforcement de l'application avant de publier votre application.
Problèmes d'intégration du SDK
Erreur « Cleartext HTTP traffic not permitted »
Erreur « Didn't find class BasicHttpParams »
Configuration NDK
Référence API
Paramètres courants
1. Initialisation via la méthode Init
Appelez la méthode Init lors de l'initialisation du SDK dans votre classe Application.
DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret);
2. Définition des domaines pour la pré-résolution
Enregistrez les domaines auprès du SDK HTTPDNS lors de l'initialisation pour activer la pré-résolution et réduire la latence ultérieure :
Spécifiez la pré-résolution pour les domaines IPv4 ou IPv6
// Specify the record type for pre-resolution. Replace the placeholder domains with the ones you want to resolve.
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...});
// DNSResolver.QTYPE_IPV4: Pre-fetches the IPv4 record type for the domain.
// DNSResolver.QTYPE_IPV6: Pre-fetches the IPv6 record type for the domain.
// DNSResolver.QTYPE_IPV4_IPV6: Pre-fetches both IPv4 and IPv6 record types for the domain.
Sélectionnez automatiquement IPv4 ou IPv6 pour la pré-résolution en fonction du réseau actuel. Dans un environnement à double pile, les adresses IPv4 et IPv6 sont toutes deux préchargées.
DNSResolver.getInstance().preLoadDomains(domains);
L'API de pré-résolution déclenche des requêtes réseau asynchrones en temps réel. Assurez-vous que toutes les initialisations nécessaires sont terminées avant d'appeler cette API.
3. Définition des domaines pour le maintien actif du cache
Le SDK résout à nouveau les domaines configurés lorsque 75 % du TTL est écoulé afin de maintenir le cache à jour. Nous vous recommandons de limiter cette opération à 10 domaines. Cette fonction est indépendante de la pré-résolution.
DNSResolver.setKeepAliveDomains(new String[]{"your-domain-1", "your-domain-2"});
Avantages
Les enregistrements sont mis à jour en temps opportun (avant l'expiration du TTL).
Lorsqu'elle est utilisée conjointement avec la pré-résolution, la latence de résolution initiale peut être réduite à 0 ms.
Inconvénients
La nouvelle requête effectuée à 75 % du TTL engendre des coûts supplémentaires.
4. Spécification de l'utilisation d'une adresse de serveur IPv6
Le service HTTPDNS prend en charge l'accès via IPv4 et IPv6. Utilisez DNSResolver.setEnableIPv6(boolean enable) pour basculer l'accès au serveur IPv6. Par défaut : IPv4. Si IPv6 est activé et que la connexion au service HTTPDNS échoue, le SDK réessaie automatiquement une fois via IPv4.
5. Définition du nombre maximal d'entrées de cache
DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); // Sets the maximum number of cache entries. The default is 100.
Vous pouvez personnaliser la valeur maximale de count.
6. Définition du protocole d'accès au serveur
Le SDK prend en charge les protocoles HTTP et HTTPS pour les requêtes de résolution. Par défaut : HTTPS (recommandé pour des raisons de sécurité). Notez que les requêtes HTTPS sont facturées cinq fois plus cher que les requêtes HTTP. Choisissez le protocole en fonction de vos besoins métier.HTTPDNS
DNSResolver.setSchemaType(DNSResolver.HTTPS); // The default access mode is HTTPS.
DNSResolver.HTTP : accède aux interfaces côté serveur via HTTP.
DNSResolver.HTTPS : accède aux interfaces côté serveur via HTTPS.
Paramètres avancés
1. Activer ou désactiver la journalisation de débogage du SDK
DNSResolver.setEnableLogger(true); // SDK debug logs are disabled by default.
Active ou désactive la journalisation de débogage du SDK. Par défaut : désactivé.
2. Spécifiez s'il faut activer le basculement automatique d'HTTPDNS vers le DNS local en cas d'échec de la résolution HTTPDNS
DNSResolver.setEnableLocalDns(true); // By default, automatic fallback to local DNS is enabled when HTTPDNS resolution fails.
3. Activer ou désactiver le mode court
L'API JSON DoH d'HTTPDNS renvoie les données dans deux formats : un JSON complet et un tableau d'adresses IP compact. Vous pouvez appeler DNSResolver.setEnableShort(boolean enable) pour activer ou désactiver le mode court. Par défaut, le mode court est désactivé.
DNSResolver.setEnableShort(true); // The default value is false. You do not need to set this parameter.
En mode court, le SDK HTTPDNS renvoie un tableau d'adresses IP compact au lieu d'un JSON complet, ce qui réduit la taille de la réponse. Cette option convient aux scénarios sensibles au trafic.
4. Spécifiez s'il faut activer un cache non expirable
DNSResolver.setImmutableCacheEnable(false); // By default, the non-expiring cache is disabled.
Le SDK propose trois mécanismes de mise à jour du cache :
-
Le cache n'expire jamais : lorsqu'elle est activée, cette fonctionnalité considère le cache comme toujours valide pendant l'exécution de l'application en ignorant les vérifications d'expiration et les opérations de mise à jour. Il n'est pas nécessaire de configurer
setKeepAliveDomainspour mettre à jour activement le cache, ce qui minimise le nombre de résolutions utilisateur.Méthode :
DNSResolver.setImmutableCacheEnable(boolean var0)Lorsque le paramètre
var0est défini surtrue, la fonctionnalité de cache non expirable est activée. Lorsquevar0est défini surfalse, cette fonctionnalité est désactivée. -
Mise à jour active du cache : cette fonctionnalité garantit que les résolutions utilisent les enregistrements mis en cache les plus récents. Lorsque la zone autoritaire d'un domaine change, ce mécanisme assure que les requêtes de résolution exploitent le cache pour réduire la latence DNS tout en récupérant les derniers enregistrements. Lorsque 75 % du TTL d'un domaine est écoulé, le SDK déclenche automatiquement une requête de résolution pour mettre à jour le cache. Nous vous recommandons de limiter à 10 le nombre de domaines pour lesquels les mises à jour actives sont activées.
Méthode :
DNSResolver.setKeepAliveDomains(String[] var1)Description :
var1est un tableau de chaînes contenant les noms de domaine à mettre à jour de manière proactive. -
Mise à jour passive du cache :
Lorsque vous appelez les deux méthodes suivantes pour obtenir les résultats de résolution, le cache est mis à jour passivement :
La méthode
getIPsV4ByHost(String hostName)récupère un tableau d'enregistrements IPv4 pour lehostNamespécifié. Si le cache n'est pas vide et se trouve dans sa période TTL, la méthode renvoie directement le résultat mis en cache. Sinon, elle récupère d'abord le dernier résultat de résolution via une requête réseau, puis renvoie ce résultat et met à jour le cache. Cette méthode est souvent utilisée dans les scénarios nécessitant des résultats de résolution très précis.-
La méthode
getIpv4ByHostFromCache(String hostName, boolean isAllowExp)récupère un tableau d'enregistrements IPv4 pour un nom d'hôte à partir du cache. Selon la valeur du paramètreisAllowExp, cette méthode détermine s'il faut renvoyer les résultats de résolution expirés depuis le cache. Nous vous recommandons d'utiliser cette méthode avec une méthode de préchargement au démarrage de l'application afin de garantir que les derniers résultats de résolution soient mis en cache.Si
isAllowExpest défini surtrue, les données obsolètes sont renvoyées même si le cache a expiré (nullest renvoyé si le cache est vide), et le cache est mis à jour via une requête asynchrone. Si ce paramètre est défini surfalse,nullest renvoyé lorsque le cache est expiré ou vide, et le cache est mis à jour via une requête asynchrone.
Modèle recommandé :
String[] IPArray = mDNSResolver.getIpv4ByHostFromCache(hostname,true); if (IPArray == null || IPArray.length == 0){ IPArray = mDNSResolver.getIPsV4ByHost(hostname); }
5. Activer ou désactiver le cache
DNSResolver.setEnableCache(true); // The cache is enabled by default.
Active ou désactive le cache de résolution. Par défaut : activé.
6. Activer ou désactiver le test de vitesse des adresses IP. Cette fonctionnalité est désactivée par défaut dans les versions 2.3.0 et antérieures, et activée par défaut dans les versions 2.3.1 et ultérieures.
DNSResolver.setEnableSpeedTest(false); // Disabled by default in v2.3.0 and earlier; enabled by default in v2.3.1 and later.
Active ou désactive le test de vitesse des adresses IP. Par défaut : désactivé dans les versions v2.3.0 et antérieures, activé dans les versions v2.3.1 et ultérieures.
7. Définissez le numéro de port pour le test de vitesse des adresses IP via la surveillance de socket
DNSResolver.setSpeedPort(DNSResolver.PORT_80);
Définit le port pour le test de vitesse des adresses IP basé sur les sockets. Par défaut : 80.
8. Définissez la marge de préférence IPv6 pour le test de vitesse des adresses IP (pris en charge dans les versions v2.3.3 et ultérieures)
DNSResolver.setSpeedTestIpv6PreferMs(0);
Définit la marge de préférence IPv6, en millisecondes, pour le test de vitesse des adresses IP. Lorsque le test de vitesse est activé et que les adresses IPv4 et IPv6 sont classées ensemble, le SDK soustrait cette marge du temps mesuré pour l'IPv6 avant de comparer ce résultat avec le temps mesuré pour l'IPv4. Une adresse IPv6 est donc toujours préférée lorsque l'IPv6 est plus lent que l'IPv4 de moins que la marge. Par défaut : 0, ce qui désactive la marge. Plage valide : [0, 1000]. Ce paramètre prend effet uniquement lorsque le test de vitesse est activé.
9. Spécifiez s'il faut partitionner le cache de domaine par réseau ISP
DNSResolver.setIspEnable(true); // By default, the domain cache is partitioned by ISP network.
Lorsqu'elle est activée, les données du cache de domaine sont stockées séparément pour chaque environnement réseau. Lorsqu'elle est désactivée, un seul cache est partagé entre tous les réseaux.
10. Définissez le TTL maximal pour le cache négatif
DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE); // Sets the maximum TTL for the negative cache. The default is 30 seconds.
Définit le TTL maximal pour le cache négatif. Une entrée de cache négatif est créée lorsqu'aucune adresse IP n'est renvoyée pour un domaine. Par défaut : 30 secondes.
11. Définissez le TTL maximal pour le cache
DNSResolver.setMaxTtlCache(MAX_TTL_CACHE); // Sets the maximum TTL for the cache. The default value is 3,600 seconds.
Définit une limite maximale de TTL pour les entrées du cache. Par défaut : 3 600 secondes.
12. Définissez les informations de sous-réseau client
DNSResolver.setEdnsSubnet("1.2.XX.XX/24");
setEdnsSubnet prend en charge EDNS Client Subnet (ECS, RFC 7871), en transmettant les informations de sous-réseau utilisateur au DNS autoritaire pour une planification précise du trafic. Un masque plus long fournit des résultats plus précis ; un masque plus court améliore la confidentialité. Un masque /24 est recommandé.
Ce paramètre est conçu pour les scénarios où un proxy DNS utilise l'API JSON DoH. Dans ces scénarios, un utilisateur envoie une requête DNS au proxy DNS, et le proxy utilise ce paramètre pour transmettre les informations de sous-réseau de l'utilisateur à HTTPDNS puis au serveur DNS autoritaire.
Par exemple, si vous appelez DNSResolver.setEdnsSubnet("1.2.XX.XX/24"), le serveur autoritaire reçoit les informations de préfixe basées sur l'adresse 1.2.XX.XX/24 pour vous aider à sélectionner un lien DNS.
13. Définissez le délai d'attente pour la résolution des noms de domaine
Définit le timeout pour la résolution de domaine. Par défaut : 3 secondes. Plage recommandée : 2–5 secondes.
DNSResolver.setTimeout(3);
14. Définissez le nombre maximal de résolutions simultanées (pris en charge dans les versions v2.3.2 et ultérieures)
Définit le nombre maximal de résolutions DNS asynchrones simultanées (pré-résolution, actualisation du cache). Plage valide : [1, 50]. Par défaut : 10.
DNSResolver.setMaxConcurrentResolveCount(10);
15. Obtenez le SessionId pour le dépannage
Un sessionId est généré au démarrage de l'application et reste constant tout au long du cycle de vie. Toutes les requêtes de résolution HTTPDNS contiennent cet ID. Utilisez-le pour tracer les requêtes sur le serveur à des fins de dépannage.
public static String getSessionId()
16. Rappel de sortie des journaux
Ce rappel reçoit les journaux générés par le SDK.
HttpDnsLog.setLogger(new ILogger() {
@Override
public void log(String msg) {
Log.d("HttpDnsLogger:", msg);
}
});
Configuration ProGuard
-keep class com.alibaba.pdns.** {*;}
API de service
/**
* Pre-loads domain name resolution based on the automatically detected network environment (IPv4-only, IPv6-only, or dual-stack).
* In a dual-stack network environment, both IPv4 and IPv6 resolution results are pre-loaded. You can call this method during SDK initialization at app startup.
* This method pre-stores the resolution results in the cache to reduce the latency of subsequent domain name resolutions.
*
* @param domains The domain names to be pre-loaded.
*/
public void preLoadDomains(final String[] domains)
/**
* Pre-loads domain resolution for a specified record type (IPv4 or IPv6).
* You can call this method during SDK initialization at app startup. This method pre-stores the resolution results in the cache to reduce latency for later resolutions.
*
* @param qType The record type to pre-load, such as IPv4 or IPv6.
* @param domains The domain names to be pre-loaded.
*/
public void preLoadDomains(String qType, final String[] domains)
/**
* Obtains the resolution data for the domain name based on the automatically detected network environment (IPv4-only, IPv6-only, or dual-stack).
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
*
* @param host The domain name that you want to resolve.
* @return The optimal IP address array based on the current network environment.
*/
public String[] getIpsByHost(String host)
/**
* Obtains the array of IPv4 records that correspond to the hostname.
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
*
* @param hostName The hostname, such as www.example.com.
* @return The array of IPv4 addresses that correspond to the hostname.
*/
public String[] getIPsV4ByHost(String hostName)
/**
* Obtains the array of IPv6 records that correspond to the hostname.
* @param hostName The hostname, such as www.example.com.
* @return The array of IPv6 addresses that correspond to the hostname.
*/
public String[] getIPsV6ByHost(String hostName)
/**
* Obtains the IP address array for the resolved domain name from the cache based on the automatically detected network environment (IPv4-only, IPv6-only, or dual-stack).
* If the cache is empty, this method returns null and initiates an asynchronous query. The query result is then stored in the cache.
* If a resolution result exists in the cache and you allow returning expired results, the expired IP addresses are returned, and the cache is updated asynchronously.
* If you do not allow returning expired results and the cached result has expired, this method returns null and then asynchronously updates the cache.
*
* @param host The host to query, such as www.example.com.
* @param isAllowExp Specifies whether to return the resolution data of an expired domain.
* @return The cached IP address array for the resolved host.
*/
public String[] getIpsByHostFromCache(String host, boolean isAllowExp)
/**
* Obtains the IP address array of the IPv4 record type for the resolved domain name from the cache.
* If the cache is empty, this method returns null and initiates an asynchronous query. The query result is then stored in the cache.
* If a resolution result exists in the cache and you allow returning expired results, the expired IP addresses are returned, and the cache is updated asynchronously.
* If you do not allow returning expired results and the cached result has expired, this method returns null and then asynchronously updates the cache.
*
* @param host The host to query, such as www.example.com.
* @param isAllowExp Specifies whether to return the resolution data of an expired domain.
* @return The IP address array of the IPv4 record type from the cache after the host is resolved.
*/
public String[] getIpv4ByHostFromCache(String host , boolean isAllowExp)
/**
* Obtains the IP address array of the IPv6 record type for the resolved domain name from the cache.
* If the cache is empty, this method returns null and initiates an asynchronous query. The query result is then stored in the cache.
* If a resolution result exists in the cache and you allow returning expired results, the expired IP addresses are returned, and the cache is updated asynchronously.
* If you do not allow returning expired results and the cached result has expired, this method returns null and then asynchronously updates the cache.
*
* @param host The host to query, such as www.example.com.
* @param isAllowExp Specifies whether to return the resolution data of an expired domain.
* @return The IP address array of the IPv6 record type from the cache after the host is resolved.
*/
public String[] getIpv6ByHostFromCache(String host , boolean isAllowExp)
/**
* Obtains the array of DomainInfo objects for IPv4 records that correspond to the URL.
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
*
* @param url The URL, such as http://www.example.com.
* @return The array of DomainInfo objects of the IPv4 type that correspond to the URL.
*/
public DomainInfo[] getIPsV4DInfoByUrl(String url)
Note: The URL in the DomainInfo object is the URL in which the host is automatically replaced with an IP address. You do not need to manually replace the host in the URL.
/**
* Obtains the array of DomainInfo objects for IPv6 records that correspond to the URL.
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
*
* @param url The URL, such as http://m.example.com.
* @return The array of DomainInfo objects of the IPv6 type that correspond to the URL.
*/
public DomainInfo[] getIPsV6DInfoByUrl(String url)
/**
* Obtains a DomainInfo object for the IPv4 records that correspond to a specific URL.
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
*
* @param url The URL, such as http://m.example.com.
* @return A random DomainInfo object from the collection of IPv4-type DomainInfo objects that correspond to the URL.
*/
public DomainInfo getIPV4DInfoByUrl(String url)
/**
* Obtains a DomainInfo object for the IPv6 records that correspond to a specific URL.
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
*
* @param url The URL, such as http://www.example.com.
* @return A random DomainInfo object from the collection of IPv6-type DomainInfo objects that correspond to the URL.
*/
public DomainInfo getIPV6DInfoByUrl(String url)
Note: The returned DomainInfo object encapsulates the following properties.
/**
* The auto-incrementing ID for the access domain.
*/
public String id = null;
/**
* The URL that can be directly used. The host in the URL is replaced with an IP address.
*/
public String url = null;
/**
* The name of the destination service to be set in the HTTP header.
*/
public String host = "";
/**
* The returned content body.
*/
public String data = null;
/**
* The time when the request starts.
*/
public String startTime = null;
/**
* The time when the request ends. If the request times out, this value is null.
*/
public String stopTime = null;
/**
* The status code returned by the server, such as 200, 404, or 500.
*/
public String code = null;
/**
* Obtains the IPv4 record that corresponds to the hostname.
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
* @param hostName The hostname, such as www.example.com.
* @return A random IPv4 address from the set of IPv4 addresses that correspond to the hostname. If IP speed testing is enabled, the optimal IPv4 address is returned.
*/
public String getIPV4ByHost(String hostName)
/**
* Obtains the IPv6 record that corresponds to the hostname.
* If a non-expired resolution result exists in the cache, the result from the cache is returned.
* If the cache is empty or the cached result has expired, a synchronous network request is sent to the server to obtain the recursive resolution result. The result is then returned and stored in the cache.
* @param hostName The hostname, such as www.example.com.
* @return A random IPv6 address from the set of IPv6 addresses that correspond to the hostname. If IP speed testing is enabled, the optimal IPv6 address is returned.
*/
public String getIPV6ByHost(String hostName)
/**
* Obtains the statistics about successful and failed HTTPDNS requests.
*
* @return A JSON array string of the resolution statistics for all domain names.
*/
public String getRequestReportInfo()
/**
* Sets domain names for cache keep-alive. The resolution of a configured domain name is automatically initiated when 75% of the TTL elapses. This ensures that resolution requests for the configured domain name always hit the cache and improves the resolution efficiency of the SDK.
* We recommend that you do not configure an excessive number of domain names for this feature. The current limit is 10 domain names. This feature is configured independently of the pre-resolution feature.
*
* @param persistentCacheDomains
*/
public synchronized static void setKeepAliveDomains(String[] persistentCacheDomains) {
/**
* Clears the cache for specified domain names. If the hostname is null, the cache for all domain names is cleared.
*
* @param domains The array of domain names whose cache you want to clear.
*/
public void clearHostCache(String[] domains){
Exemples d'API
URL : l'adresse d'accès transmise, par exemple http://www.example.com.
String hostname = "www.taobao.com";
String url = "http://www.taobao.com";
1. Obtenir les données IP optimales pour l'environnement réseau actuel
String[] ip = DNSResolver.getInstance().getIpsByHost(hostname); // Gets the optimal domain resolution IP for the current network.
2. Précharger la résolution de domaine en fonction de l'environnement réseau actuel
DNSResolver.getInstance().preLoadDomains(domains); // Sets domain names for pre-resolution. Replace the placeholder domains with the ones you want HTTPDNS to resolve.
3. Lire les données de résolution de domaine depuis le cache en fonction de l'environnement réseau actuel
String[] ip = DNSResolver.getInstance().getIpsByHostFromCache(hostname,true); // Gets domain resolution data from the cache for the current network environment.
4. Obtenir une adresse IPv4
String IPV4 = DNSResolver.getInstance().getIPV4ByHost(hostname); // Gets the resolved IPv4 address.
5. Obtenir une adresse IPv6
String IPV6 = DNSResolver.getInstance().getIPV6ByHost(hostname); // Gets the resolved IPv6 address.
6. Obtenir une adresse IPv4 résolue depuis le cache
String[] IPV4 = DNSResolver.getInstance().getIpv4ByHostFromCache(hostname , true); // Gets the resolved IPv4 address from the cache.
7. Obtenir une adresse IPv6 résolue depuis le cache
String[] IPV6 = DNSResolver.getInstance().getIpv6ByHostFromCache(hostname , true); // Gets the resolved IPv6 address from the cache.
8. Obtenir l'objet DomainInfo correspondant à une URL
DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(url); // Gets the replaced URL.
9. Effacer le résultat de résolution d'un domaine spécifié du cache
DNSResolver.getInstance().clearHostCache(hostName); // Clears the cache for a specified domain. If hostName is set to null, the cache for all domains is cleared.
10. Obtenir des statistiques sur les requêtes HTTPDNS réussies et échouées
String reportInfo = DNSResolver.getInstance().getRequestReportInfo(); // Gets statistics about successful and failed requests.
Le tableau suivant décrit les champs du tableau de chaînes JSON contenant les statistiques de résolution de domaine.
[
{
"avgRtt":"1", // Average domain resolution time, in milliseconds (ms).
"degradeLocalDnsCount": 0, // Number of fallbacks to local DNS.
"domainName":"www.example.com", // The resolved domain name.
"hitDnsCacheCount": 1, // Number of cache hits.
"httpabnormalCount": 0, // Number of failed recursive requests.
"isp": "China Mobile", // ISP name.
"localDnsResolveErrCount": 0, // Number of local DNS resolution failures.
"maxRtt": 8.0, // Maximum domain resolution time, in milliseconds (ms).
"nonetworkCount": 0, // Number of times the network is unavailable.
"permissionErrCount": 0, // Number of user authentication failures.
"queryType": 1, // IP type. 1 indicates IPv4, and 28 indicates IPv6.
"recursiveReqCount": 1, // Number of recursive queries.
"reqParameterErrCount": 0, // Number of request parameter format errors.
"reqPathErrCount": 0, // Number of URL errors.
"reqServerErrCount": 0, // Number of DNS server-side errors.
"reqTimeoutCount": 0, // Number of DNS service timeout errors.
"resolveSuccessCount": 1, // Number of successful resolutions.
"timeoutCount": 0, // Number of network timeout errors.
"utfNetWorkErroNum": 0 // Number of data reporting timeout errors.
}
......
]
Les statistiques des requêtes de résolution de domaine HTTPDNS sont agrégées par environnement réseau, nom de domaine et type de requête.
Exemple
public class MainActivity extends AppCompatActivity {
private Button button;
private TextView tvInfo;
private TextView tvResult;
private String hostUrl = "http://www.taobao.com"; // Replace this with the hostUrl that you want to resolve.
private String hostName = "www.taobao.com"; // Replace this with the hostName that you want to resolve.
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() {
// Call the getIPV4ByHost method in the HTTPDNS SDK to obtain the resolved IP address of the target domain name.
String ip = DNSResolver.getInstance().getIPV4ByHost(hostName);
if(ip != null){
tvInfo.setText("The resolved IP for the domain is: "+ ip);
}
// Call the getIPV4DInfoByUrl method in the HTTPDNS SDK to get the URL from the resolved DomainInfo object.
// The host in this URL is replaced with the IP address.
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) {
// Sends a network request.
String requestUrl = dinfo.url;
HttpURLConnection conn = null;
try {
URL url = new URL(requestUrl);
conn = (HttpURLConnection) url.openConnection();
// When you use an IP address for access, you must set the Host field of the HTTP request header to the original domain name.
conn.setRequestProperty("Host", url.getHost()); // Sets the Host field of the HTTP request header.
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 accountId = "Your Account ID"; // Set your Account ID from the console.
private String accessKeyId = "Your AccessKey ID"; // Set your AccessKey ID from the console.
private String accessKeySecret = "Your AccessKey Secret"; // Set your AccessKey Secret from the console.
@Override
public void onCreate() {
super.onCreate();
// Set the Account ID, AccessKey ID, and AccessKey Secret for SDK access.
DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret);
// Sets domain names for cache keep-alive. The resolution of a configured domain name is automatically initiated at 75% of its TTL to ensure that resolution requests for the domain name always hit the cache.
DNSResolver.setKeepAliveDomains(new String[]{"your-domain-1","your-domain-2",...});
// Pre-loads specified domains to IPv4 addresses. Replace the placeholder domains with the ones that you want to resolve.
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"your-domain-to-preload-1","your-domain-to-preload-2",...});
}
}
Bonnes pratiques
Combinez la pré-résolution avec la mise en cache des réponses expirées pour des performances optimales.
La pré-résolution met en cache les résultats au démarrage. Autoriser les réponses expirées permet de renvoyer immédiatement les IP mises en cache même après l'expiration du TTL, ce qui permet d'obtenir une résolution avec une latence quasi nulle.
Les domaines préchargés atteignent le cache local lors des requêtes suivantes, éliminant ainsi les allers-retours réseau.
1. Pré-résolution
Activez la mise en cache et pré-résolvez les domaines clés au démarrage de l'application.
Dans la méthode onCreate() de Application, pré-résolvez vos domaines et mettez en cache les résultats localement.
1. Scénarios IPv4 uniquement
//********For IPv4-only scenarios*******
public class DnsCacheApplication extends Application{
private String accountId = "Your Account ID"; // Set your Account ID from the console.
private String accessKeyId = "Your AccessKey ID"; // Set your AccessKey ID from the console.
private String accessKeySecret = "Your AccessKey Secret"; // Set your AccessKey Secret from the console.
@Override
public void onCreate() {
super.onCreate();
// Set the Account ID, AccessKey ID, and AccessKey Secret for SDK access.
DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret);
DNSResolver.setEnableCache(true); // Enable caching. Default value: true.
// The IPv4 record type for pre-resolution.
// Pre-loads specified domains to IPv4 addresses. Replace the placeholder domains with the ones that you want HTTPDNS to resolve.
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"your-domain-to-preload-1","your-domain-to-preload-2",...});
}
}
2. Prise en charge d'IPv6
//********For scenarios that require IPv6 support*******
public class DnsCacheApplication extends Application{
private String accountId = "Your Account ID"; // Set your Account ID from the console.
private String accessKeyId = "Your AccessKey ID"; // Set your AccessKey ID from the console.
private String accessKeySecret = "Your AccessKey Secret"; // Set your AccessKey Secret from the console.
@Override
public void onCreate() {
super.onCreate();
// Set the Account ID, AccessKey ID, and AccessKey Secret for SDK access.
DNSResolver.Init(this, accountId, accessKeyId, accessKeySecret);
DNSResolver.setEnableCache(true); // Enable caching. Default value: true.
DNSResolver.setEnableIPv6(true); // Specifies whether to resolve domain names over an IPv6 network. Default value: false.
DNSResolver.setEnableSpeedTest(true); // Specifies whether to enable IP speed testing. Default value: false.
// The IPv4 and IPv6 record types for pre-resolution.
// Pre-loads specified domains to IPv4 and IPv6 addresses. Replace the placeholder domains with the ones that you want HTTPDNS to resolve.
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4_IPV6,new String[]{"your-domain-to-preload-1","your-domain-to-preload-2",...});
}
}
2. Autoriser les réponses expirées
Lisez les IP depuis le cache avant les requêtes réseau, en permettant le renvoi immédiat des entrées expirées. Le cache est mis à jour de manière asynchrone en arrière-plan.
1. Scénarios IPv4 uniquement
//********For IPv4-only scenarios*******
@Override
public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
// Prioritize getting the IP address from the cache. The second parameter, if true, allows returning expired but usable records.
String[] IPArray = mDNSResolver.getIpv4ByHostFromCache(hostname,true);
if (IPArray == null || IPArray.length == 0){
// If the cache is not hit, initiate an asynchronous resolution.
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. Prise en charge d'IPv6
//********For scenarios that require IPv6 support*******
@Override
public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
// Prioritize getting the IP address from the cache. The second parameter, if true, allows returning expired but usable records.
String[] IPArray = mDNSResolver.getIpsByHostFromCache(hostname,true);
if (IPArray == null || IPArray.length == 0){
// If the cache is not hit, initiate an asynchronous resolution.
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);
}
Remarques d'utilisation
Lorsque vous utilisez une adresse IP obtenue depuis HTTPDNS pour envoyer des requêtes, définissez l'en-tête HTTP
Hostsur le nom de domaine d'origine.-
Si le SDK HTTPDNS renvoie une IP vide, revenez à l'URL du nom de domaine d'origine :
String ip = DNSResolver.getInstance().getIPV4ByHost("your-domain"); if (ip != null) { // Replace the host in the URL with the IP address to make an API request. }else { // Use the request URL of the original domain name to make a fallback request. // In this case, use the original URL that contains the domain name to make a network request. } Téléchargez le programme de démonstration comme référence pour l'intégration du SDK HTTPDNS.
Après l'intégration, vérifiez le succès sur la page Analyse du trafic dans la console. Si aucun trafic n'apparaît, vérifiez que l'Account ID, l'AccessKey ID et l'AccessKey Secret sont correctement définis.
DNS sur site
À partir de la version 2.3.0, le SDK Android HTTPDNS ajoute la prise en charge du déploiement DNS sur site.
Le DNS sur site convient aux scénarios exigeant la conformité des données et des politiques de résolution personnalisées (finance, gouvernement, grandes entreprises). Le SDK prend en charge quatre modes de déploiement : cloud public uniquement, sur site uniquement et deux hybrides principal-secondaire.
Fonctionnalités principales
Prise en charge du déploiement sur site : permet de configurer les endpoints de service DNS sur site à l'aide d'adresses IPv4/IPv6 ou de noms de domaine hôtes.
Authentification bidirectionnelle : ce mécanisme signe les requêtes avec un
accessKeyIdet unaccessKeySecretspécifiques au client afin de garantir une communication sécurisée.Disjoncteur et contrôles de santé : si un nœud DNS sur site échoue 3 fois ou plus consécutivement, le disjoncteur est automatiquement déclenché. Par la suite, sa disponibilité est vérifiée chaque minute à l'aide du
healthCheckDomainspécifié. Le nœud est automatiquement réactivé après sa récupération.Contrôle de la validation des certificats : à partir de la version 2.3.1.beta, vous pouvez désactiver la validation des certificats TLS pour tester le DNS sur site. Les versions beta sont destinées uniquement aux tests et ne doivent pas être utilisées en production. Note de publication du SDK Android
Basculement intelligent : si le DNS principal (DNS cloud public ou DNS sur site) échoue à résoudre un nom de domaine et que le nombre d'échecs atteint le seuil spécifié, le système bascule automatiquement vers le DNS secondaire pour garantir une haute disponibilité de la résolution.
Compatibilité API transparente : que vous utilisiez le DNS cloud public ou le DNS sur site, la manière d'appeler l'API de résolution reste la même. Vous n'avez pas besoin de modifier votre logique métier.
Configuration
1. DNS cloud public uniquement
Ce mode est destiné aux utilisateurs SaaS standard qui n'ont pas déployé de DNS sur site.
DNSResolver.Init(this, accountID, accessKeyId, accessKeySecret);
2. DNS sur site uniquement
Ce mode est destiné aux clients qui s'appuient entièrement sur leur DNS sur site.
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");
// Optional: Disable certificate validation (for test environments only, requires a beta SDK version, e.g., 2.3.1.beta).
// DNSResolver.setEnableCertificateValidation(false);
3. Principal : Cloud public, secondaire : Sur site
Si le HTTPDNS public Alibaba Cloud principal échoue à résoudre un nom de domaine, le système revient automatiquement au DNS sur site.
// Primary: public cloud DNS
DNSResolver.Init(this, accountID, accessKeyId, accessKeySecret);
// Standby: on-premises DNS
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");
// Optional: Disable certificate validation (for test environments only, requires a beta SDK version, e.g., 2.3.1.beta).
// DNSResolver.setEnableCertificateValidation(false);
4. Principal : Sur site, secondaire : Cloud public
Utilisez le DNS sur site comme DNS principal. Si le DNS sur site échoue à résoudre un nom de domaine, le système revient automatiquement au DNS cloud public Alibaba Cloud.
// Primary: on-premises DNS
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");
// Optional: Disable certificate validation (for test environments only, requires a beta SDK version, e.g., 2.3.1.beta).
// DNSResolver.setEnableCertificateValidation(false);
// Standby: public cloud DNS
DNSResolver.Init(this, accountID, accessKeyId, accessKeySecret);
Nouvelles API
Le SDK ajoute trois API principales pour le déploiement sur site et la reprise après sinistre à haute disponibilité :
1. Configurer les endpoints et l'authentification
/** For on-premises DNS used in on-premises deployments. You do not need to call this method if you use only public DNS.
*
* Sets the address and authentication information for the on-premises DNS server.
* Customers use this interface to pass the address and authentication credentials of the private DNS server.
* The SDK uses this information to initiate requests.
* @param ctx The context.
* @param serverIpv4Arr The array of IPv4 addresses (can be nil).
* @param serverIpv6Arr The array of IPv6 addresses (can be nil).
* @param serverHostArr The array of host domain names (can be nil).
* @param port The service port, such as "443". If nil, the default port "443" is used.
* @param healthCheckDomain The domain name that is used for health checks after circuit breaking is triggered. When a resolution service consecutively fails more than three times, circuit breaking is triggered, and the IP address of that service enters the healthCheck state. Subsequent requests will not be sent to this service.
* A timer runs every minute to call the resolution API by using this healthCheckDomain to probe whether the resolution service is available. If the probe is successful, the service returns to the alive state, and subsequent requests can be sent to this service.
* @param accessKeyId The customer's private accessKeyId, which is used for authentication.
* @param accessKeySecret The customer's private accessKeySecret, which is used for authentication.
*/
public static void InitFusionDNS(Context ctx,String[] serverIpv4Arr, String[] serverIpv6Arr, String[] serverHostArr, String port, String healthCheckDomain, String accessKeyId, String accessKeySecret)
2. Contrôler la validation des certificats TLS
Contrôlez la validation des certificats TLS pour le DNS sur site. Les builds beta du SDK Android sont publiés à partir de la version 2.3.1, et le build beta correspondant à la version 2.3.1 est nommé 2.3.1.beta. Un build beta vous permet de désactiver la validation des certificats TLS pour le DNS sur site afin d'effectuer des tests. Les builds beta existent uniquement pour faciliter les tests. N'utilisez jamais un build beta dans un environnement de production.
/** For on-premises DNS used in on-premises deployments. You do not need to call this method if you use only public DNS.
*
* Specifies whether to enable certificate validation for on-premises DNS. Default value: true. If the server is not configured with a domain certificate or an IP certificate, you can set this parameter to false for testing. In production environments, we strongly recommend that you set this parameter to true. Otherwise, security risks may arise.
* @param enable Set this parameter to true to enable certificate validation (default), or false to disable it.
*/
public static void setEnableCertificateValidation(boolean enable)
3. Définir le seuil de basculement
/** If you configure both public cloud DNS and on-premises DNS, you can specify the number of times that DNS resolution on the primary DNS must fail before the system automatically falls back to the standby DNS. If you configure only one type of DNS, you do not need to call this method.
*
* Specifies the number of times that DNS resolution on the primary DNS must fail before the system automatically falls back to the standby DNS. If you configure only one type of DNS, you do not need to call this method.
* @param fallbackThreshold The failure threshold. Default: 4 if the primary DNS is public cloud DNS, or 2 if the primary DNS is on-premises DNS.
* Valid range: [0, 4]. A value of 0 indicates an immediate fallback.
*/
public static void setFallbackThreshold(int fallbackThreshold)