このトピックでは、カスタム開発用のアプリに Alibaba Cloud パブリック DNS SDK for Android を統合する方法について説明します。
1. 概要
Alibaba Cloud パブリック DNS SDK は、モバイル開発者に Domain Name System ( DNS ) 解決サービスを提供するために Alibaba Cloud によって開発されました。
この SDK を使用すると、モバイル開発者は Android アプリから Alibaba Cloud パブリック DNS に簡単にアクセスできます。 これにより、DNS 解決エラーを防ぎ、低コストで DNS クエリの正確なスケジューリングを実現します。 デモプロジェクトのソースコードは、SDK を Android アプリに統合する方法と、Android アプリで Alibaba Cloud パブリック DNS を使用する方法の例を提供します。
この SDK は、Alibaba Cloud パブリック DNS の DoH 用 JSON API をカプセル化しています。 この SDK は、Android アプリが DNS 解決を実行するための Java 関数インターフェイスを提供します。 この SDK は、time to live ( TTL ) と least recently used ( LRU ) ポリシーに基づいて、DNS 結果を効果的にキャッシュするためにも使用できます。 この SDK は、Alibaba Cloud パブリック DNS の機能に基づいて、次の利点を提供します。
使いやすさ
Alibaba Cloud パブリック DNS を使用するには、SDK をアプリに統合するだけで済みます。 これにより、より簡単で便利な方法で解決サービスを使用できます。
遅延のない DNS 解決
SDK は LRU キャッシングアルゴリズムを実装しているため、DNS 解決で取得した IP アドレスはオンプレミスサーバーにキャッシュされます。 また、SDK はキャッシュされたデータを自動的に更新し、TTL に基づいて期限切れのデータを削除します。 これにより、キャッシュされたデータは有効なままであり、遅延なく DNS 解決を実行できます。
2. SDK の統合
Alibaba Cloud DNS コンソールでアプリを登録し、アプリの [アカウント ID] を取得します。
次に、プロジェクトディレクトリの AndroidManifest.xml ファイルで、認証用の [アクセスキー ID] パラメータと [アクセスキー シークレット] パラメータを指定します。
SDK をアプリプロジェクトに統合します。
2.1 build.gradle ファイルに Maven リポジトリを追加する
build.gradle ファイルに次のコードを追加します。
allprojects {
repositories {
maven {
url 'https://maven.aliyun.com/repository/public/'
}
mavenLocal()
mavenCentral()
}
}
参照するファイル情報を追加します。
dependencies {
implementation 'com.alibaba.pdns:alidns-android-sdk:2.2.7'
implementation 'com.google.code.gson:gson:2.8.5'
}
2.2 SDK AAR パッケージをプロジェクトに統合する
Alibaba Cloud DNS をクリックして、Alibaba Cloud DNS コンソールで Alibaba Cloud パブリック DNS の SDK AAR パッケージ alidns_android_sdk.aar を取得します。 パッケージをプロジェクトの libs ディレクトリに解凍して SDK をインストールします。 その後、SDK を使用できます。
上記のいずれかの方法を使用して、SDK をプロジェクトに統合できます。
2.3 SDK の初期化
SDK をより効果的に使用し、IP アドレスの取得に失敗しないようにするには、できるだけ早く SDK を初期化することをお勧めします。
Alibaba Cloud DNS コンソールでアプリを登録し、アプリの [アカウント ID] を取得してから、認証用の [アクセスキー ID] と [アクセスキー シークレット] を取得する必要があります。 SDK をアプリプロジェクトに統合した後、SDK を初期化できます。 SDK を初期化する方法の詳細については、アプリの次のサンプルコードを参照してください。
public class DnsCacheApplication extends Application{
private String Account ID = "Your Account ID"; // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアカウント ID を指定します。
private String AccessKey ID = "Your AccessKey ID"; // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアクセスキー ID を指定します。
private String AccessKey Secret = "Your AccessKey Secret"; // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアクセスキー シークレットを指定します。
@Override
public void onCreate() {
super.onCreate();
DNSResolver.Init(this, Account ID, AccessKey ID, AccessKey Secret); // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアカウント ID、アクセスキー ID、およびアクセスキー シークレットを指定します。
//注: キャッシュ保持機能を有効にするドメイン名を指定します。 キャッシュ保持機能が有効になると、TTL 期間の 75% が経過すると、ドメイン名が自動的に解決されます。 これにより、ドメイン名に対する DNS リクエストは、解決中に常にキャッシュされた DNS 結果と一致します。 Alibaba Cloud Content Delivery Network ( CDN ) にドメイン名を追加すると、TTL の短縮によって DNS リクエスト数が増加し、課金が増える可能性があります。 このコマンドを実行する際は注意してください。
DNSResolver.setKeepAliveDomains(new String[]{"キャッシュ保持機能を有効にするドメイン名 1","キャッシュ保持機能を有効にするドメイン名 2",...});
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"DNS 結果をプリロードするドメイン名 1","DNS 結果をプリロードするドメイン名 2",...}); // 事前に解決し、Alibaba Cloud パブリック DNS を使用して解決する IPv4 ドメイン名を指定します。
}
}
DNSResolver は、Alibaba Cloud パブリック DNS SDK のコアクラスです。 DNSResolver は、目的のドメイン名を対応する IP アドレスに解決するために、Alibaba Cloud パブリック DNS によって提供される DoH 用 JSON API をカプセル化します。 SDK を使用して Alibaba Cloud パブリック DNS にアクセスする場合は、SDK を Android アプリの Application クラスに統合することをお勧めします。
Android プロジェクトで SDK を使用する場合、次のアクセス許可が構成されていることを確認してください。
<!--必要な権限-->
<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"/>
2.4 SDK 認証
SDK 2.0 以降を使用して認証を有効にし、許可されていない第三者によるユーザー ID の盗難を防ぐことができます。 Alibaba Cloud DNS コンソールで [アクセスキー ID] と [アクセスキー シークレット] を作成して認証を有効にする方法の詳細については、「サービス認証」をご参照ください。 SDK の初期化時に認証用のパラメータを指定しないと、Alibaba Cloud パブリック DNS は認証が無効になっているドメイン名に対する DNS リクエストを拒否します。 これにより、DNS 解決に失敗し、ビジネスに影響が出ます。 したがって、SDK を初期化するときは、認証用のパラメータを指定する必要があります。
ビジネス要件に基づいて認証用のパラメータを指定するには、次のコマンドを実行します。
DNSResolver.Init(this, Account ID, AccessKey ID, AccessKey Secret);
アカウント ID、アクセスキー ID、アクセスキー シークレット、またはアプリケーションの実行中に生成されたデータの漏洩を防ぐため、SDK のデバッグログを無効にすることをお勧めします。
ユーザーが同じ SDK を使用するため、アクセス中にコード内でアカウント ID/アクセスキー ID/アクセスキー シークレットパラメータが指定されていることを確認してください。 これらのパラメータは、計測と課金に密接に関連しています。 悪意のある逆コンパイルによる情報漏洩を防ぐため、アプリケーションをロールアウトする前に、難読化を有効にし、アプリケーションを強化することをお勧めします。
3. SDK ベースのアクセスに関する一般的な問題
Android 9.0 を実行しているデバイスが HTTP リクエストを送信すると、「クリアテキスト HTTP トラフィックは許可されていません」というエラーメッセージが返されます。
原因: デフォルトでは、Android 9.0 ( Android SDK プラットフォームの API レベル 28 ) 以降の Android デバイスでは、プレーンテキストネットワークアクセスが無効になっています。
解決策
Android アプリの AndroidManifest.xml ファイルの <application> セクションに次の構成を追加します。
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 を実行しているデバイスを使用すると、「クラス BasicHttpParams が見つかりません」というエラーメッセージが返されます。
原因: Apache HttpClient はサポートされなくなりました。
Google は、Android 6.0 以降、Apache HttpClient のサポートを削除しました。 Android 9.0 以降では、org.apache.http.legacy が bootclasspath から削除されています。
この変更は、taskVersion が Android 9.0 より前のほとんどのアプリには影響しません。 ただし、taskVersion の値が Android 9.0 より大きいアプリを使用する場合、Apache HTTP インターフェイスが引き続き使用されているか、参照されている lib パッケージが Apache HTTP インターフェイスを使用していると、「クラス BasicHttpParams が見つかりません」というエラーメッセージが返されます。
解決策
Android アプリの AndroidManifest.xml ファイルの <application> セクションに次の構成を追加します。
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
SDK はバージョン 2.1.9 から Java Native Interface ( JNI ) を使用し始めます。 したがって、アプリプロジェクトの開発環境で Native Development Kit ( NDK ) を構成する必要があります。
アプリプロジェクトのルートディレクトリにある local.properties ファイルに NDK のインストールディレクトリを追加します。
ndk.dir=...\\ndk\\21.4.7075529 ... NDK のローカルディレクトリ。
アプリプロジェクトのルートディレクトリにある gradle.properties ファイルに次の構成を追加します。
android.useDeprecatedNdk = true
アプリプロジェクト用に NDK を構成済みの場合は、この手順をスキップしてください。 SDK をより効果的に使用するには、アプリをコンパイルするときに、Java Development Kit ( JDK ) のバージョンを 1.8 に、NDK のバージョンを 21.4.7075529 に設定することをお勧めします。
4. API の紹介
4.1 一般的な設定
4.1.1 initialize メソッドを呼び出す
アプリケーションで SDK を初期化するには、SDK initialize メソッドを呼び出すことができます。
DNSResolver.Init(this, Account ID, AccessKey ID, AccessKey Secret);
4.1.2 事前解決のドメイン名を指定する
Android アプリを初期化するときに、Alibaba Cloud パブリック DNS SDK で使用する可能性のあるドメイン名を登録して、SDK がドメイン名を事前に解決できるようにすることができます。 これにより、後続の DNS 解決時のリクエストの遅延が短縮されます。 次のコードは、事前解決するドメイン名を構成する方法を示しています。
DNS 結果をプリロードする IPv6 または IPv4 ドメイン名を指定します
// 事前に解決し、Alibaba Cloud パブリック DNS を使用して解決する IP アドレスタイプを指定します。
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...})
DNSResolver.QTYPE_IPV4 事前解決されたドメイン名に対応する IPv4 レコードタイプを取得します。
DNSResolver.QTYPE_IPV6 事前解決されたドメイン名に対応する IPv6 レコードタイプを取得します。
現在のネットワーク環境に基づいて、IPv6 または IPv4 ドメイン名の DNS 結果を自動的に照合してプリロードします。 たとえば、IPv4/IPv6 デュアルスタックネットワーク環境で IPv4 および IPv6 ドメイン名の DNS 結果をプリロードします。
DNSResolver.getInstance().preLoadDomains(domains)
事前解決インターフェイスを構成すると、非同期ネットワークリクエストがリアルタイムでトリガーされます。 事前解決インターフェイスが呼び出されたときに、コードロジックに必要な初期化設定があることを確認する必要があります。
4.1.3 ドメイン名のキャッシュ保持機能を有効にする
SDK を使用すると、ドメイン名のキャッシュ保持機能を有効にできます。 キャッシュ保持機能が有効になると、TTL 期間の 75% が経過すると、ドメイン名が自動的に解決されます。 これにより、解決中にドメイン名に対する DNS リクエストが常にキャッシュされた DNS 結果と一致するため、SDK の解決効率が向上します。 最大 10 個のドメイン名に対してキャッシュ保持機能を有効にし、事前解決されたドメイン名を個別に指定することをお勧めします。
DNSResolver.setKeepAliveDomains(new String[]{"キャッシュ保持機能を有効にするドメイン名 1", "キャッシュ保持機能を有効にするドメイン名 2"});
メリット:
1. TTL 期間が満了する前に DNS レコードをタイムリーに更新できます。
2. ドメイン名が初めて解決された場合、ドメイン名の DNS レコードがプリロードされると、解決レイテンシを 0 ミリ秒に短縮できます。
デメリット:
TTL 期間の 75% が経過したときにドメイン名に対する別の DNS リクエストが開始されると、追加料金が発生します。
4.1.4 サーバーの IPv6 アドレスを使用するかどうかを指定する
Alibaba Cloud パブリック DNS は、IPv4 および IPv6 デュアルスタックアクセスをサポートしています。 DNSResolver.setEnableIPv6(boolean enable) を指定して、サーバーの IPv6 アドレスを使用するかどうかを決定できます。 DNSResolver.setEnableIPv6(boolean enable) を true に設定すると、サーバーインターフェイスへのアクセスに IPv6 アドレスが使用されます。 DNSResolver.setEnableIPv6(boolean enable) を false に設定すると、サーバーインターフェイスへのアクセスに IPv4 アドレスが使用されます。 DNSResolver.setEnableIPv6(boolean enable) を指定しないと、デフォルトで IPv4 アドレスがアクセスに使用されます。 IPv6 アドレスがアクセスに使用されている場合、Alibaba Cloud パブリック DNS にアクセスできなくなると、システムは自動的に IPv4 アドレスに切り替えます。 この場合、最大 3 回のアクセス再試行が許可されます。
4.1.5 キャッシュできる DNS 結果の最大数を指定する
DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); // キャッシュできる DNS 結果の最大数を指定します。 デフォルト値は 100 です。
ビジネス要件に基づいて CACHE_MAX_NUMBER パラメータを指定できます。
4.1.6 サーバーアクセスプロトコルを指定する
SDK は、HTTP または HTTPS 経由の DNS 解決をサポートしています。 HTTP または HTTPS 経由で DNS 解決を実行するかどうかを指定できます。 デフォルトでは、SDK は HTTPS 経由で DNS 解決を実行します。これは、HTTPS の方がセキュリティが高いためです。 Alibaba Cloud パブリック DNS は、HTTP 経由の DNS 解決回数に基づいて課金されます。 HTTPS 経由の DNS 解決 1 回は、HTTP 経由の DNS 解決 5 回に相当します。 ビジネス要件に基づいて適切なプロトコルを選択できます。
DNSResolver.setSchemaType(DNSResolver.HTTPS); サーバーアクセスプロトコルを指定します。 デフォルトのアクセスプロトコルは HTTPS です。
DNSResolver.HTTP は、サーバーアクセスに HTTP が使用されることを示します。
DNSResolver.HTTPS は、サーバーアクセスに HTTPS が使用されることを示します。
4.1.7 IP アドレスの接続速度テスト用のソケットのポート番号を指定する
DNSResolver.setSpeedPort(DNSResolver.PORT_80)
IP アドレスの接続速度テスト用のソケットのポート番号を指定できます。 デフォルトのポート番号は 80 です。
4.2 詳細設定
4.2.1 ログデバッグを有効にするかどうかを指定する
DNSResolver.setEnableLogger(true); // デフォルトでは、ログデバッグは無効になっています。
ログデバッグを有効にするかどうかを指定できます。 setEnableLogger を true に設定すると、ログデバッグが有効になります。 setEnableLogger を false に設定すると、ログデバッグが無効になります。
4.2.2 Alibaba Cloud パブリック DNS を使用した解決に失敗した場合に、ローカル DNS サーバーを使用して解決するかどうかを指定する
DNSResolver.setEnableLocalDns(true); //デフォルトでは、Alibaba Cloud パブリック DNS を使用した解決に失敗した場合、システムは自動的にローカル DNS サーバーを使用して解決します。
4.2.3 ショートモードを有効にするかどうかを設定する
Alibaba Cloud パブリック DNS の DoH 用 JSON API によって返されるデータは、JSON 形式または IP アドレスの単純な配列にすることができます。 DNSResolver.setEnableShort (boolean enable) を指定して、ショートモードを有効または無効にできます。 DNSResolver.setEnableShort (boolean enable) を指定しないと、デフォルトでショートモードは無効になります。 次のサンプルコードは、ショートモードの構成を示しています。
DNSResolver.setEnableShort (true); // デフォルト値は false です。 このパラメータを指定しないと、デフォルト値が使用されます。
ショートモードでは、SDK は Alibaba Cloud パブリック DNS を呼び出して、IP アドレスの単純な配列を返します。 これにより、返されるデータ量が削減され、大量のネットワークトラフィックが許可されていないシナリオに適しています。
4.2.4 キャッシュを期限切れにしないように設定する
DNSResolver.setImmutableCacheEnable(false); // デフォルトでは、キャッシュは期限切れに設定されています。
SDK は、3 つのキャッシュ更新メカニズムを提供します。
キャッシュは期限切れになりません。 キャッシュが期限切れにならないように設定した後、アプリの実行中はキャッシュが常に有効であると判断され、期限切れのチェックや期限切れのキャッシュの更新は行われません。
setKeepAliveDomains
パラメータを指定してキャッシュをアクティブに更新する必要はありません。 これにより、DNS 解決の回数を最小限に抑えることができます。方法:
DNSResolver.setImmutableCacheEnable(boolean var0)
パラメータを使用して、キャッシュが期限切れにならないように設定できます。説明:
var0
をtrue
に設定すると、キャッシュは期限切れになりません。var0
をfalse
に設定すると、キャッシュは期限切れになります。キャッシュはアクティブに更新されます: このメカニズムは、DNS リクエストが常にキャッシュされた DNS 結果と一致するようにするためのものです。 権限のある DNS 解決ルールが変更された場合、この方法を使用して、解決中に DNS リクエストが常にキャッシュされた DNS 結果と一致するようにすることができます。 これにより、DNS 解決のネットワークレイテンシを削減し、最新の DNS レコードがキャッシュされるようにすることができます。 設定に基づいて、TTL 期間の 75% が経過すると、DNS クエリが自動的に開始され、キャッシュされたデータが更新されます。 最大 10 個のドメイン名に対してキャッシュ保持機能を有効にすることをお勧めします。
方法:
DNSResolver.setKeepAliveDomains(String[] var1)
パラメータを使用して、キャッシュをアクティブに更新するように設定できます。説明:
var1
は、アクティブに更新する必要があるすべてのドメイン名の解決統計情報の配列文字列を指します。キャッシュはパッシブに更新されます:
次の 2 つの方法を使用して、キャッシュをパッシブに更新するように設定できます。
getIPsV4ByHost(String hostName)
解決方法を使用する場合: キャッシュに DNS 結果が存在し、期限切れになっていない場合、A レコードでホスト名がマッピングされている IPV4 アドレスがキャッシュから取得され、DNS 結果が返されます。 キャッシュに DNS 結果が存在しないか、キャッシュされた DNS 結果が期限切れになっている場合、DNS 結果を取得するために DNS サーバーに DNS リクエストが再帰的に送信されます。 取得された DNS 結果が返され、キャッシュされます。 この方法は、DNS 結果の精度を高める必要があるシナリオ向けに設計されています。getIpv4ByHostFromCache(String hostName, boolean isAllowExp)
解決方法を使用する場合: A レコードでホスト名がマッピングされている IPV4 アドレスがキャッシュから取得されます。isAllowExp
パラメータを構成して、キャッシュ内の期限切れの DNS 結果を返すかどうかを指定できます。 アプリの起動時にドメイン名の DNS 結果をプリロードすることをお勧めします。 これにより、アプリの起動後に最新の DNS 結果をキャッシュできます。説明: キャッシュにデータが存在しない場合は、
null
が返されます。この場合、DNS 結果を取得するための非同期リクエストが開始され、結果が返されてキャッシュに格納されます。isAllowExp
をtrue
に設定すると、有効期限が切れたキャッシュされた IP アドレスが返される場合があります。isAllowExp
をfalse
に設定すると、キャッシュの有効期限が切れたときにnull
が返され、非同期リクエストが開始された後にキャッシュが更新されます。
サンプルコード:
String[] IPArray = mDNSResolver.getIpv4ByHostFromCache(hostname,true); if (IPArray == null || IPArray.length == 0){ IPArray = mDNSResolver.getIPsV4ByHost(hostname); }
4.2.5 キャッシュ機能を有効にするかどうかを指定する
DNSResolver.setEnableCache(true); // キャッシュ機能を有効にするかどうかを指定します。 この機能はデフォルトで有効になっています。
setEnableCache を true に設定すると、キャッシュ機能が有効になります。 setEnableCache を false に設定すると、キャッシュ機能が無効になります。
4.2.6 IP アドレスの接続速度テストを有効にするかどうかを指定する
DNSResolver.setEnableSpeedTest(false); // IP アドレスの接続速度テストを有効にするかどうかを指定します。 この機能はデフォルトで無効になっています。
setEnableSpeedTest を true に設定すると、この機能が有効になります。 setEnableSpeedTest を false に設定すると、この機能が無効になります。
4.2.7 ISP ネットワークによる DNS 結果のキャッシュを有効にするかどうかを指定する
DNSResolver.setIspEnable(true);// インターネットサービスプロバイダー ( ISP ) ネットワークによる DNS 結果のキャッシュを有効にするかどうかを指定します。
ISP ネットワークによる DNS 結果のキャッシュを有効にするかどうかを指定できます。 setIspEnable を true に設定すると、ネットワーク環境に基づいて DNS 結果が個別にキャッシュされます。 setIspEnable を false に設定すると、異なるネットワークで同じキャッシュされた DNS 結果が使用されます。
4.2.8 ネガティブキャッシュの最大 TTL 期間を指定する
DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);// ネガティブキャッシュの最大 TTL 期間を指定します。 デフォルト値は 30 です。 単位: 秒。
ビジネス要件に基づいて、ネガティブキャッシュの最大 TTL 期間を指定できます。 ネガティブキャッシュとは、IP アドレスが構成されていないドメイン名に対するネガティブレスポンスの保存を意味します。
4.2.9 DNS 結果をキャッシュするための最大 TTL 期間を指定する
DNSResolver.setMaxTtlCache(MAX_TTL_CACHE);// DNS 結果をキャッシュするための最大 TTL 期間を指定します。 デフォルト値は 3600 です。 単位: 秒。
SDK を使用して、DNS 結果をキャッシュするための最大 TTL を指定できます。 maxCacheTTL パラメータを構成する場合、DNS 結果をキャッシュするための最大 TTL はこのパラメータの値を超えることはできません。 SDK では、このパラメータのデフォルト値は 3600 秒です。
4.2.10 クライアントのサブネット情報を指定する
DNSResolver.setEdnsSubnet("1.2.XX.XX/24");
edns_client_subnet パラメータは、RFC 7871 仕様で指定されている EDNS Client Subnet ( ECS ) をサポートするために設計されています。 ECS は、正確な DNS 解決とトラフィックスケジューリングを実現するために、ユーザーに関するサブネット情報を権限のある DNS サーバーに転送する DNS 拡張機能です。 マスクが長いほどアドレス情報が正確になりますが、マスクが短いほどユーザーのプライバシーが保護されます。 マスク長として /24 を使用することをお勧めします。
このパラメータは、DNS プロキシが DoH 用 JSON API を使用するシナリオ向けに設計されています。 DNS プロキシは、ユーザーから DNS リクエストを受信した後、edns_client_subnet パラメータを使用して、ユーザーに関するサブネット情報を Alibaba Cloud パブリック DNS に渡します。 次に、Alibaba Cloud パブリック DNS はサブネット情報を権限のある DNS サーバーに渡します。
たとえば、edns_client_subnet の値が 1.2.XX.XX/24 の場合、権限のある DNS サーバーは 1.2.XX.XX/24 のプレフィックスに基づいてユーザーの DNS ルートを選択します。
4.2.11 DNS 解決のタイムアウト期間を構成する
timeout
パラメータは、DNS 解決のタイムアウト期間を指定します。 デフォルトのタイムアウト期間は 3 秒です。 ビジネス要件に基づいてカスタムタイムアウト期間を指定できます。 タイムアウト期間は 2 ~ 5 秒の範囲内の値に設定することをお勧めします。
DNSResolver.setTimeout(3);
5. 難読化対策の構成
-keep class com.alibaba.pdns.** {*;}
6. サービス API 操作
/**
* 現在のネットワーク環境でサポートされている IP アドレスタイプを自動的に検出して、ドメイン名の DNS 結果をプリロードします。 ネットワーク環境は、IPv4 のみ、IPv6 のみ、または IPv4/IPv6 デュアルスタックです。
* IPv4/IPv6 デュアルスタックネットワーク環境でサポートされている IP アドレスタイプを自動的に検出して、ドメイン名の DNS 結果を取得します。 アプリを起動した後、
* この操作を呼び出して DNS 結果をキャッシュできます。 これにより、後続の DNS 解決が高速化されます。
*
* @param domains DNS 結果がプリロードされるドメイン名。
*/
public void preLoadDomains(final String[] domains)
/**
* DNS 結果をプリロードする IPv6 または IPv4 ドメイン名を指定します。
* アプリを起動した後、この操作を呼び出して DNS 結果をキャッシュできます。 これにより、後続の DNS 解決が高速化されます。
*
* @param qType プリロードする IP アドレスタイプ ( IPv4 または IPv6 など )。
* @param domains プリロードされる解決済みドメイン名。
*/
public void preLoadDomains(String qType, final String[] domains)
/**
* 現在のネットワーク環境でサポートされている IP アドレスタイプを自動的に検出して、ドメイン名の DNS 結果を取得します。 ネットワーク環境は、IPv4 のみ、IPv6 のみ、または IPv4/IPv6 デュアルスタックです。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
*
* @param host 解決するドメイン名。
* @return 現在のネットワーク環境に基づいて最適な IP アドレスの配列を取得します。
*/
public String[] getIpsByHost(String host)
/**
* 特定のホスト名に対応する IPv4 レコードの配列を取得します。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
*
* @param hostName 例: www.taobao.com
* @return ホスト名に対応する IPv4 アドレスの配列が返されます。
*/
public String[] getIPsV4ByHost(String hostName)
/**
* 特定のホスト名に対応する IPv6 レコードの配列を取得します。
* @param hostName 例: www.taobao.com
* @return ホスト名に対応する IPv6 アドレスの配列が返されます。
*/
public String[] getIPsV6ByHost(String hostName)
/**
* 現在のネットワーク環境でサポートされている IP アドレスタイプを自動的に検出して、ドメイン名が解決された後にキャッシュから IP アドレスの配列を取得します。 ネットワーク環境は、IPv4 のみ、IPv6 のみ、または IPv4/IPv6 デュアルスタックです。
* キャッシュに IP アドレス配列が存在しない場合は、null が返されます。 その後、非同期クエリがトリガーされ、クエリ結果がキャッシュに保存されます。
* キャッシュされた DNS 結果が期限切れになった場合、許可されている場合は、期限切れの DNS 結果が最初にクライアントに返されます。 その後、キャッシュされた DNS 結果が非同期に更新されます。
* キャッシュ内の期限切れの DNS 結果を返すことが許可されていない場合は、最初に null が返されます。 その後、キャッシュされた DNS 結果が非同期に更新されます。
*
* @param host クエリするドメイン名 ( www.taobao.com など )。
* @param isAllowExp ドメイン名が期限切れになった場合に DNS 結果を返すかどうかを指定します。
* @return ドメイン名が解決された後にキャッシュから IP アドレスの配列を取得します。
*/
public String[] getIpsByHostFromCache(String host, boolean isAllowExp)
/**
* ドメイン名が解決された後にキャッシュから IPv4 レコードタイプの IP アドレス配列を取得します。
* キャッシュに IP アドレス配列が存在しない場合は、null が返されます。 その後、非同期クエリがトリガーされ、クエリ結果がキャッシュに保存されます。
* キャッシュされた DNS 結果が期限切れになった場合、許可されている場合は、期限切れの DNS 結果が最初にクライアントに返されます。 その後、キャッシュされた DNS 結果が非同期に更新されます。
* キャッシュ内の期限切れの DNS 結果を返すことが許可されていない場合は、最初に null が返されます。 その後、キャッシュされた DNS 結果が非同期に更新されます。
*
* @param host クエリするドメイン名 ( www.taobao.com など )。
* @param isAllowExp ドメイン名が期限切れになった場合に DNS 結果を返すかどうかを指定します。
* @return ドメイン名が解決された後にキャッシュ内の IPv4 レコードタイプの IP アドレス配列が返されます。
*/
private String[] getIpv4ByHostFromCache(String host , boolean isAllowExp)
/**
* ドメイン名が解決された後にキャッシュから IPv6 レコードタイプの IP アドレス配列を取得します。
* キャッシュに IP アドレス配列が存在しない場合は、null が返されます。 その後、非同期クエリがトリガーされ、クエリ結果がキャッシュに保存されます。
* キャッシュされた DNS 結果が期限切れになった場合、許可されている場合は、期限切れの DNS 結果が最初にクライアントに返されます。 その後、キャッシュされた DNS 結果が非同期に更新されます。
* キャッシュ内の期限切れの DNS 結果を返すことが許可されていない場合は、最初に null が返されます。 その後、キャッシュされた DNS 結果が非同期に更新されます。
*
* @param host クエリするドメイン名 ( www.taobao.com など )。
* @param isAllowExp ドメイン名が期限切れになった場合に DNS 結果を返すかどうかを指定します。
* @return ドメイン名が解決された後にキャッシュ内の IPv6 レコードタイプの IP アドレス配列が返されます。
*/
private String[] getIpv6ByHostFromCache(String host , boolean isAllowExp)
/**
* 特定の URL に対応する IPv4 レコードの DomainInfo オブジェクト配列を取得します。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
*
* @param url 例: http://www.taobao.com
* @return URL に対応する IPv4 レコードの DomainInfo オブジェクト配列が返されます。
*/
public DomainInfo[] getIPsV4DInfoByUrl(String url)
注: DomainInfo オブジェクト配列の URL は、host フィールドが特定の IP アドレスに自動的に置き換えられた URL です。 URL の host フィールドを手動で置き換える必要はありません。
/**
* 特定の URL に対応する IPv6 レコードの DomainInfo オブジェクト配列を取得します。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
*
* @param url 例: http://m.taobao.com
* @return URL に対応する IPv6 レコードの DomainInfo オブジェクト配列が返されます。
*/
public DomainInfo[] getIPsV6DInfoByUrl(String url)
/**
* 特定の URL に対応する IPv4 レコードの DomainInfo オブジェクトを取得します。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
*
* @param url 例: http://m.taobao.com
* @return URL に対応する IPv4 レコードの DomainInfo オブジェクトが返されます。
*/
public DomainInfo getIPV4DInfoByUrl(String url)
/**
* 特定の URL に対応する IPv6 レコードの DomainInfo オブジェクトを取得します。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
*
* @param url 例: http://www.taobao.com
* @return URL に対応する IPv6 レコードの DomainInfo オブジェクトが返されます。
*/
public DomainInfo getIPV6DInfoByUrl(String url)
注: 返される DomainInfo オブジェクトは、次の属性をカプセル化します。
/**
* アクセスドメイン名の自動インクリメント ID。
*/
public String id = null;
/**
* host フィールドが IP アドレスに置き換えられた使用可能な URL。
*/
public String url = null;
/**
* HTTP リクエストのヘッダーに含める必要があるサービス名。
*/
public String host = "";
/**
* 返されるコンテンツ本文。
*/
public String data = null;
/**
* リクエストの開始時刻。
*/
public String startTime = null;
/**
* リクエストの終了時刻。 リクエストがタイムアウトした場合、値は null です。
*/
public String stopTime = null;
/**
* サーバーから返される状態コード ( 200、404、500 など )。
*/
public String code = null;
/**
* 特定のホスト名に対応する IPv4 レコードを取得します。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
* @param hostName 例: www.taobao.com
* @ return ホスト名に対応する IPv4 アドレスのセットからランダムな IPv4 アドレスが返されます。 IP アドレスの接続速度テストが有効になっている場合は、最適な IPv4 アドレスが返されます。
*/
public String getIPV4ByHost(String hostName)
/**
* 特定のホスト名に対応する IPv6 レコードを取得します。
* DNS 結果がキャッシュに存在し、期限切れになっていない場合は、キャッシュされた DNS 結果が返されます。
* キャッシュされたデータが存在しないか、キャッシュされたデータが期限切れになっている場合は、再帰 DNS リクエストが DNS サーバーに送信され、DNS 結果が取得されます。その後、DNS 結果がクライアントに返され、キャッシュされます。
* @param hostName 例: www.taobao.com
* @return ホスト名に対応する IPv6 アドレスのセットからランダムな IPv6 アドレスが返されます。 IP アドレスの接続速度テストが有効になっている場合は、最適な IPv6 アドレスが返されます。
*/
public String getIPV6ByHost(String hostName)
/**
* Alibaba Cloud パブリック DNS のクエリ成功とクエリ失敗の統計情報を取得します。
*
* @return すべてのドメイン名の解決統計情報の JSON 配列文字列が返されます。
*/
public String getRequestReportInfo()
/**
* キャッシュ保持機能を有効にするドメイン名を指定します。 キャッシュ保持機能が有効になると、TTL 期間の 75% が経過すると、ドメイン名が自動的に解決されます。 これにより、解決中にドメイン名に対する DNS リクエストが常にキャッシュされた DNS 結果と一致するため、SDK の解決効率が向上します。
最大 10 個のドメイン名に対してキャッシュ保持機能を有効にすることをお勧めします。 事前解決されたドメイン名を個別に指定する必要があります。
*
* @param persistentCacheDomains
*/
public synchronized static void setKeepAliveDomains(String[] persistentCacheDomains) {
/**
* 指定されたドメイン名のキャッシュをクリアします。 hostName パラメータが null に設定されている場合、すべてのドメイン名のキャッシュがクリアされます。
*
* @param domains キャッシュがクリアされるドメイン名の配列を指定します。
*/
public void clearHostCache(String[] domains){
7. SDK API 操作の例
URL: 受信したアクセスアドレス ( http://www.taobao.com など )。
String hostname = "www.taobao.com";
String url = "http://www.taobao.com";
7.1 現在のネットワーク環境に基づいて最適な IP アドレスを取得する
String[] ip = DNSResolver.getInstance().getIpsByHost(hostname); // ドメイン名が解決された後に、現在のネットワーク環境に基づいて最適な IP アドレスを取得します。
7.2 現在のネットワーク環境に基づいてドメイン名の DNS 結果をプリロードする
DNSResolver.getInstance().preLoadDomains(domains) // 事前に解決し、Alibaba Cloud パブリック DNS を使用して解決するドメイン名を指定します。
7.3 現在のネットワーク環境に基づいてキャッシュから DNS 結果を取得する
String[] ip = DNSResolver.getInstance().getIpsByHostFromCache(hostname,true);// ドメイン名が解決された後に、現在のネットワーク環境に基づいてキャッシュから IP アドレスを取得します。
7.4 IPv4 アドレスを取得する
String IPV4 = DNSResolver.getInstance().getIPV4ByHost(hostname); // ドメイン名が解決された後に IPv4 アドレスを取得します。
7.5 IPv6 アドレスを取得する
String IPV6 = DNSResolver.getInstance().getIPV6ByHost(hostname) // ドメイン名が解決された後に IPv6 アドレスを取得します。
7.6 ドメイン名が解決された後にキャッシュから IPv4 アドレスを取得する
String[] IPV4 = DNSResolver.getInstance().getIpv4ByHostFromCache(hostname, true) // ドメイン名が解決された後にキャッシュから IPv4 アドレスを取得します。
7.7 ドメイン名が解決された後にキャッシュから IPv6 アドレスを取得する
String[] IPV6 = DNSResolver.getInstance().getIpv6ByHostFromCache(hostname, true) // ドメイン名が解決された後にキャッシュから IPv6 アドレスを取得します。
7.8 特定の URL に対応する DomainInfo オブジェクトを取得する
DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(url); // ドメイン名が IP アドレスに置き換えられた URL を取得します。
7.9 指定されたドメイン名のキャッシュされた DNS 結果をクリアする
DNSResolver.getInstance().clearHostCache(hostName); // 指定されたドメイン名のキャッシュされた DNS 結果をクリアします。 hostName パラメータが null に設定されている場合、すべてのドメイン名のキャッシュされた DNS 結果がクリアされます。
7.10 Alibaba Cloud パブリック DNS のクエリ成功とクエリ失敗の統計情報を取得する
String reportInfo = DNSResolver.getInstance().getRequestReportInfo();// クエリ成功とクエリ失敗の統計情報を取得します。
次のセクションでは、すべてのドメイン名の解決統計情報の JSON 配列文字列のフィールドの意味を示します。
[
{
"avgRtt":"1", // 平均 DNS 解決時間。 単位: ミリ秒。
"degradeLocalDnsCount": 0, // DNS 解決がローカル DNS サーバーにダウングレードされた回数。
"domainName":"www.example.com", // 解決するドメイン名。
"hitDnsCacheCount": 1, // キャッシュヒット数。
"httpabnormalCount": 0, // 再帰 DNS リクエストが失敗した回数。
"isp": "China Mobile", // ISP の名前。
"localDnsResolveErrCount": 0, // ローカル DNS サーバーでの DNS 解決の失敗回数。
"maxRtt": 8.0, // 最大 DNS 解決時間。 単位: ミリ秒。
"nonetworkCount": 0, // ネットワークが失敗した回数。
"permissionErrCount": 0, // 認証の失敗回数。
"queryType": 1, // type パラメータの値が 1 の場合は IPv4 アドレスが使用されます。 type パラメータの値が 28 の場合は IPv6 アドレスが使用されます。
"recursiveReqCount": 1, // 再帰 DNS クエリの数。
"reqParameterErrCount": 0, // リクエストパラメータが無効なために返されたエラーの数。
"reqPathErrCount": 0, // URL が無効なために返されたエラーの数。
"reqServerErrCount": 0, // DNS サーバーの障害のために返されたエラーの数。
"reqTimeoutCount": 0, // DNS リクエストがタイムアウトしたためにレスポンスが返されなかった回数。
"resolveSuccessCount": 1, // DNS 解決の成功回数。
"timeoutCount": 0, // ネットワークタイムアウトエラーの数。
"utfNetWorkErroNum": 0 // データレポートがタイムアウトしたために返されたエラーの数。
}
......
]
Alibaba Cloud パブリック DNS の解決統計情報は、ネットワーク環境、ドメイン名、およびクエリタイプに基づいて収集されます。
8. 例
public class MainActivity extends AppCompatActivity {
private Button button;
private TextView tvInfo;
private TextView tvResult;
private String hostUrl = "http://www.taobao.com"; // http://www.taobao.com を、解決するドメイン名に対応する URL に置き換えます。
private String hostName = "www.taobao.com"; // www.taobao.com を、解決するドメイン名に置き換えます。
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() {
// Alibaba Cloud パブリック DNS SDK の getIPV4ByHost メソッドを呼び出して、指定されたドメイン名から解決された IP アドレスを取得します。
String ip = DNSResolver.getInstance().getIPV4ByHost(hostName);
if(ip != null){
tvInfo.setText("ドメイン名から解決された IP アドレス: "+ ip);
}
// Alibaba Cloud パブリック DNS SDK の getIPV4DInfoByUrl メソッドを呼び出して、指定されたドメイン名が解決された後に DomainInfo オブジェクトの URL を取得します。 URL では、host フィールドが IP アドレスに置き換えられています。
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) {
// ネットワークリクエストを送信します。
String requestUrl = dinfo.url;
HttpURLConnection conn = null;
try {
URL url = new URL(requestUrl);
conn = (HttpURLConnection) url.openConnection();
// IP アドレスを使用してアクセスする場合は、HTTP リクエストヘッダーの Host フィールドを解決されたドメイン名に設定する必要があります。
conn.setRequestProperty("Host", url.getHost());// HTTP リクエストヘッダーの Host フィールドを指定します。
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"; // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアカウント ID を指定します。
private String AccessKey ID = "Your AccessKey ID"; // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアクセスキー ID を指定します。
private String AccessKey Secret = "Your AccessKey secret"; // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアクセスキー シークレットを指定します。
@Override
public void onCreate() {
super.onCreate();
DNSResolver.Init(this, Account ID, AccessKey ID, AccessKey Secret); // Alibaba Cloud DNS コンソールで SDK にアクセスするために使用するアカウント ID、アクセスキー ID、およびアクセスキー シークレットを指定します。
DNSResolver.setKeepAliveDomains(new String[]{"キャッシュ保持機能を有効にするドメイン名 1","キャッシュ保持機能を有効にするドメイン名 2",...}); // キャッシュ保持機能を有効にするドメイン名を指定します。 TTL 期間の 75% が経過すると、ドメイン名が自動的に解決されます。 これにより、解決中にドメイン名に対する DNS リクエストが常にキャッシュされた DNS 結果と一致します。
DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{"DNS 結果をプリロードするドメイン名 1","DNS 結果をプリロードするドメイン名 2",...}); // 事前に解決し、Alibaba Cloud パブリック DNS を使用して解決する IPv4 ドメイン名を指定します。
}
}
使用上の注意
Alibaba Cloud パブリック DNS を使用してドメイン名を IP アドレスに解決した後、その IP アドレスを使用してビジネスリクエストを送信できます。 HTTP リクエストヘッダーの Host フィールドを、解決されたドメイン名として指定する必要があります。
通常のサービス実行を確保するために、Alibaba Cloud パブリック DNS SDK を使用してドメイン名がマッピングされている IP アドレスを取得しない場合は、元のドメイン名の URL を使用してリクエストを送信する必要があります。 次のセクションでは、サンプルコードを示します。
String ip = DNSResolver.getInstance().getIPV4ByHost("ドメイン名"); if (ip != null) { // URL のホスト名を IP アドレスに置き換えてリクエストを送信します。 }else { // 元のドメイン名の URL を使用してリクエストを送信します。 }
デモプロジェクトは、Alibaba Cloud パブリック DNS SDK の使用方法を学ぶのに役立ちます。 デモプロジェクトをダウンロードして参照できます。
アプリが Alibaba Cloud パブリック DNS SDK と統合されているかどうかを確認するには、Alibaba Cloud DNS コンソールの [再帰的解決 ( パブリック DNS )] ページの [トラフィック分析] タブでトラフィックを確認します。 トラフィックが生成されない場合は、[アカウント ID]、[アクセスキー ID]、および [アクセスキー シークレット] パラメータの値が有効かどうかを確認します。