このドキュメントでは、HTTPDNS iOS SDK の統合方法と使用方法について説明します。
概要
iOS SDK は、HTTPDNS の DoH JSON API をカプセル化しています。iOS アプリにドメイン名前解決機能を提供し、Time-to-Live (TTL) と Least Recently Used (LRU) ポリシーに基づいた効率的なドメイン名キャッシュ機能を備えています。この SDK を使用することで、HTTPDNS を iOS アプリに簡単に統合し、ドメイン名前解決の例外を解決し、ドメイン名前解決のための高精度かつ低コストのスケジューリングを実現できます。
iOS 14 以降、システムは DNS over TLS (DoT) と DNS over HTTPS (DoH) という 2 つの標準的な暗号化 DNS プロトコルをネイティブにサポートしています。HTTPDNS をデフォルトの暗号化 DNS リゾルバとして設定する方法の詳細については、「iOS 14 ネイティブ暗号化 DNS ソリューション」をご参照ください。
SDK には次の利点があります。
シンプルで使いやすい
SDK を統合して HTTPDNS サービスにアクセスします。統合方法はシンプルで、便利な名前解決サービスを提供します。
ゼロレイテンシー
SDK は内部 LRU キャッシュメカニズムを実装し、ドメイン名前解決から得られた IP アドレスをローカルにキャッシュします。また、期限切れのキャッシュエントリを積極的に更新し、キャッシュデータの適時性と有効性を維持します。これにより、ゼロレイテンシーのドメイン名前解決を実現できます。
この SDK を Objective-C プロジェクトで使用する方法の詳細については、alidns_ios_demo サンプルプロジェクトのソースコードをご参照ください。
この SDK を Swift プロジェクトで使用する方法の詳細については、DNSResolverSwiftDemo サンプルプロジェクトのソースコードをご参照ください。
SDK の統合
SDK のインポート
CocoaPods を使用した統合
Podfile で、リポジトリの場所を指定します。Master リポジトリを省略しないでください。
source 'https://github.com/CocoaPods/Specs.git' source 'https://github.com/aliyun/aliyun-specs.git'プロジェクトターゲットに依存関係を追加します。
pod 'AlicloudPDNS'
手動での統合
詳細については、「SDK のダウンロード」をご参照ください。iOS SDK を取得できます。
SDK の
pdns-sdk-ios.frameworkを入手後、プロジェクトに手動で統合します。システムライブラリをインポートします。
Foundation.framework
SystemConfiguration.framework
CoreFoundation.framework
CoreTelephony.framework
プロジェクトのビルド設定で、[Other linker flags] セクションに -ObjC フラグを追加します。
SDK の初期化
まず、コンソールでアプリケーションを登録し、その一意の識別子と認証パラメーターを取得します。その後、統合後に SDK を初期化します。
SDK が正しく動作し、名前解決の失敗を避けるために、できるだけ早い段階で SDK を初期化してください。
application:didFinishLaunchingWithOptions: で SDK を初期化します。
DNSResolver *resolver = [DNSResolver share];
//setAccountId:@"******": アスタリスクの内容を、コンソールの [アクセス設定] ページのアカウント ID に置き換えてください。
//andAccessKeyId:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey ID に置き換えてください。
//andAccesskeySecret:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey Secret に置き換えてください。
[resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
// 期限切れキャッシュの自動更新対象ドメインを指定します。配列は最大 10 個のドメイン名に制限されます。
[resolver setKeepAliveDomains:@[@"user_specified_domain_1",@"user_specified_domain_2"]];
// 後で解決が必要になる可能性のあるドメインをプリロードします。
[resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
// すべてのドメインがプリロードされました。
}];API の概要
共通設定
1. アカウント ID と認証
これらは必須パラメーターです。コンソールでアプリケーションを登録すると、コンソールはそのアプリケーションの一意の アカウント ID を生成します。認証機能は、ユーザー ID のセキュリティを確保し、第三者による不正使用を防ぎます。詳細については、「AccessKey ペアの作成」をご参照いただき、コンソールで AccessKey を作成してください。次のコードを使用してアプリで設定します。
//setAccountId:@"******": アスタリスクの内容を、コンソールの [アクセス設定] ページのアカウント ID に置き換えてください。
//andAccessKeyId:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey ID に置き換えてください。
//andAccesskeySecret:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey Secret に置き換えてください。
[[DNSResolver share] setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];アカウント ID、AccessKey ID、AccessKey Secret、またはアプリの操作中に生成されるその他のデータがログに漏洩するのを防ぐため、リリースバージョンでは SDK のデバッグログを無効にしてください。
デモンストレーションのため、サンプルコードではアカウント ID、AccessKey ID、AccessKey Secret をプロパティとして直接渡しています。これらのパラメーターは、計測と課金に密接に関連しています。悪意のある逆コンパイルによる情報漏洩を防ぐため、本番環境ではプレーンテキストの認証情報を直接渡さないでください。たとえば、プレーンテキストの認証情報を事前にエンコードまたは暗号化し、値を渡すときにデコードまたは復号することができます。また、アプリのコードを難読化して強化することも推奨します。そうしないと、アカウント ID、AccessKey ID、AccessKey Secret が逆コンパイルによって第三者に取得される可能性があります。
2. 名前解決プロトコルの設定
SDK では、DNS 名前解決リクエストのプロトコルを設定できます。scheme プロパティを設定することで、HTTP または HTTPS 経由での名前解決を選択できます。
デフォルトでは、SDK は HTTPS プロトコルを推奨し、使用します。これは HTTPS の方がセキュリティが優れているためです。HTTPDNSは HTTP 名前解決リクエストの数に基づいて課金されます。HTTPS 名前解決リクエストは、HTTP 名前解決リクエストの 5 倍のレートで課金されます。必要に応じてスキームタイプを選択してください。プロパティを次のように設定します。
[DNSResolver share].scheme = DNSResolverSchemeHttps;3. キャッシュの有効化/無効化
SDK でキャッシュ機能を有効にできます。キャッシュが有効な場合、ドメイン名が初めて解決された後、後続の解決ではキャッシュからのデータ取得が優先されます。これにより、名前解決の速度が大幅に向上します。
SDK はデフォルトでキャッシュを有効にします。キャッシュを無効にするには、次のコードを使用します。
[DNSResolver share].cacheEnable=NO;4. ドメインのキープアライブキャッシュの設定
キャッシュが有効な場合、特定のドメインに対してキープアライブキャッシュ機能を有効にできます。この機能が有効な場合、SDK はこれらのドメインの期限切れキャッシュを自動的に更新し、キャッシュデータが最新であることを保証します。ただし、これによりドメイン名前解決の回数とクライアントのトラフィック消費量が増加する可能性があります。この機能が有効でない場合、SDK は期限切れキャッシュを自動的に更新しません。キャッシュは、名前解決メソッドを呼び出したときにのみ更新されます。特定のドメインにキープアライブキャッシュを設定するには、次のコードを使用します。
// 配列は最大 10 個のドメイン名に制限されます。
[[DNSResolver share] setKeepAliveDomains:@[@"www.taobao.com",@"www.aliyun.com"]];利点:
レコードを迅速に更新します (TTL が切れる前に)。
事前解決と併用すると、初回解決の遅延を 0 ms に短縮します。
欠点:TTL の 75% で再リクエストすると、追加のコストが発生します。
5. 事前解決
SDK のキャッシュ機能が有効なため、初回の名前解決でキャッシュエントリが生成された後、後続のリクエストではドメインの名前解決速度がゼロレイテンシーまで短縮される可能性があります。最高のパフォーマンスを得るには、アプリの起動後に解決が必要になる可能性のあるドメインを事前解決してください。
コード例:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// アプリケーション起動後のカスタマイズのためのオーバーライドポイント。
DNSResolver *resolver = [DNSResolver share];
//setAccountId:@"******": アスタリスクの内容を、コンソールの [アクセス設定] ページのアカウント ID に置き換えてください。
//andAccessKeyId:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey ID に置き換えてください。
//andAccesskeySecret:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey Secret に置き換えてください。
[resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
resolver.cacheEnable = YES;
// 後で解決が必要になる可能性のあるドメインをプリロードします。
[resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
// すべてのドメインがプリロードされました。
}];
return YES;
}高度な設定
1. サーバー側の IPv6 アドレスの使用
HTTPDNS サービスは IPv4 と IPv6 のデュアルスタックアクセスをサポートしています。デフォルトでは、SDK は IPv4 アドレスを使用して DNS サーバーにアクセスし、名前解決を行います。
IPv6 アドレス経由で DNS サーバーにアクセスして名前解決を行うには、現在のネットワークが IPv6 をサポートしている必要があります。この機能を有効にするには、次のコードを使用します。
[DNSResolver share].ipv6Enable = YES;2. 短縮モード
HTTPDNS の DoH JSON API は、完全な JSON 形式または簡潔な IP アドレス配列形式でデータを返します。デフォルトでは、SDK は完全な JSON 形式を使用します。
簡潔な IP アドレス配列形式を使用するには、次のコードを使用します。
[DNSResolver share].shortEnable = YES;3. キャッシュサイズの設定
SDK でキャッシュが有効な場合、キャッシュされるエントリ数をカスタマイズできます。サポートされる範囲は 100 から 500 です。
デフォルトのキャッシュサイズは 100 ドメイン名です。キャッシュサイズをカスタマイズするには、cacheCountLimit プロパティを設定します。
[DNSResolver share].cacheCountLimit = 200;4. IP 速度テストの有効化の設定
SDK で IP アドレスのプロービングを有効にできます。IP アドレスのプロービングが有効な場合、名前解決の結果は最も速い IP アドレスを優先します。IP アドレスの配列は、プロービング結果に基づいて速いものから遅いものへとソートされます。
SDK はデフォルトでは IP 速度テストを有効にしません。IP 速度テストを有効にするには、次のコードを使用します。
[DNSResolver share].speedTestEnable=YES;5. IP アドレスプロービングメソッドの設定
SDK は IP 速度テストのメソッドを設定できます。IP 速度テストが有効で、このパラメーターが 0 に設定されている場合、ICMP 検出が使用されます。このパラメーターが 80、443、またはその他のサポートされているポート番号に設定されている場合、ソケット固有のポート検出が使用されます。
このパラメーターのデフォルト値は 443 です。
[DNSResolver share].speedPort = 80;6. ISP 別のドメイン名キャッシュの設定
SDK を使用して、ISP ネットワークに基づいたドメイン名キャッシュを有効にできます。有効にすると、キャッシュされたドメイン名前解決の結果は、互いに影響を与えることなく、異なるネットワーク環境で個別に保存されます。有効にしない場合、同じキャッシュされたドメイン名前解決の結果が異なるネットワーク間で共有されます。
デフォルトでは、SDK は ISP ネットワークに基づいたドメイン名キャッシュの区別を有効にします。
[DNSResolver share].ispEnable = YES;7. ネガティブキャッシュの最大 TTL の設定
SDK は、ネガティブキャッシュ (IP アドレスを返さない失敗したドメイン名ルックアップのキャッシュ) の最大 TTL を設定できます。この値を設定すると、ネガティブキャッシュの最大 TTL は指定された期間を超えません。
SDK でのこのパラメーターのデフォルト値は 30 秒です。ネガティブキャッシュの最大 TTL を設定するには、次のコードを使用します。
[DNSResolver share].maxNegativeCache = 30;8. 最大キャッシュ TTL の設定
SDK を使用してキャッシュの最大 TTL を設定し、キャッシュデータの TTL がこの制限を超えないようにすることができます。
デフォルトでは、SDK はこのパラメーターを 3600 秒に設定します。最大キャッシュ TTL を設定するには、次のコードを使用します。
[DNSResolver share].maxCacheTTL= 3600;9. 不変キャッシュを有効にするかどうかの設定
[DNSResolver share].immutableCacheEnable = NO;// 不変キャッシュはデフォルトで無効になっており、期限切れになることはありませんSDK は 3 つのキャッシュ更新メカニズムを使用します。
不変キャッシュ:この機能を有効にすると、アプリのランタイム中にキャッシュが常に有効であると見なされます。SDK はキャッシュの有効期限チェックと更新をスキップし、DNS 名前解決リクエストを最小限に抑えます。
次のように設定します:
[DNSResolver share].immutableCacheEnable = YESアクティブキャッシュ更新:このメカニズムは、DNS 名前解決が最新のキャッシュレコードにヒットすることを保証します。ドメインの権威 DNS レコードが変更されると、アクティブ更新により、名前解決リクエストはキャッシュを使用できるようになり、DNS の遅延が短縮される一方で、通常はキャッシュレコードが最新の状態に保たれます。ドメインリストには最大 10 個のドメインを含めることができます。
次のように設定します:
[[DNSResolver share] setKeepAliveDomains:@[@"user-specified-domain-1",@"user-specified-domain-2"]]パッシブキャッシュ更新:次の 2 つのメソッドのいずれかを呼び出して名前解決結果を取得すると、キャッシュがパッシブに更新されます。
- (void)getIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete:ドメインの IPv4 アドレス配列を取得します。キャッシュが空でなく、TTL 内である場合、キャッシュされた結果を直接返します。それ以外の場合は、ネットワーク経由で最新の結果を取得し、それを返してキャッシュを更新します。名前解決結果に高い精度が必要な場合に使用します。- (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable:キャッシュから IPv4 名前解決結果を取得します。このメソッドは、enableパラメーターの値に基づいて、期限切れのキャッシュエントリを返します。メトリックの説明:
enableがYESの場合、キャッシュが期限切れであっても古いレコードを返します (キャッシュが空の場合はnilを返します)。そして、非同期リクエストを使用してキャッシュを更新します。NOの場合、キャッシュが期限切れまたは空のときにnilを返し、非同期リクエストを使用してキャッシュを更新します。
10. タイムアウト
timeout プロパティは、ドメイン名前解決のタイムアウトを指定します。デフォルトのタイムアウトは 3 秒です。ユーザーはタイムアウトをカスタマイズでき、2 秒から 5 秒の間に設定することが推奨されます。
サービス API
コード例:
/// ドメイン情報を事前解決します。これはプログラムの開始時に呼び出すことができます。解決結果はキャッシュに保存され、後続のドメイン名前解決を高速化します。
/// ネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動検出し、現在のネットワークに適した IP アドレスを解決します。
/// @param domainArray ドメイン名の配列。
/// @param complete 解決完了後のコールバック。
- (void)preloadDomains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;
/// ドメイン名前解決後の IP アドレスの配列を取得します。ネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動検出し、現在のネットワークに適した IP アドレスを取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべての IP アドレス)。
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;
/// ネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動検出し、現在のネットワークに適した IP アドレスの配列をキャッシュから直接、待機せずに取得します。
/// キャッシュがない場合は nil を返します。キャッシュがあり、enable が YES に設定されている場合、キャッシュデータを返し、データが期限切れの場合はドメイン名を非同期で解決してキャッシュを更新します。キャッシュがあり、enable が NO に設定されている場合、キャッシュが期限切れのときに nil を返し、ドメイン名を非同期で解決してキャッシュを更新します。
/// @param domain ドメイン名。
/// @param enable 期限切れの IP アドレスを返すことを許可するかどうかを指定します。
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;
/// ドメイン名前解決後の IPv4 情報の配列を取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべてのドメイン情報)。
- (void)getIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;
/// ドメイン名前解決後の IPv6 情報の配列を取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべてのドメイン情報)。
- (void)getIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;
/// ドメイン名前解決後の IPv4 情報を取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべてのドメイン情報からランダムなエントリ)。
- (void)getRandomIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;
/// ドメイン名前解決後の IPv6 情報を取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべてのドメイン情報からランダムなエントリ)。
- (void)getRandomIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;
/// ドメイン名前解決後の IPv4 アドレスの配列を取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべての IP アドレス)。
- (void)getIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;
/// ドメイン名前解決後の IPv6 アドレスの配列を取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべての IP アドレス)。
- (void)getIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;
/// ドメイン名前解決後の IPv4 アドレスを取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべての IP アドレスからランダムなアドレス)。
- (void)getRandomIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;
/// ドメイン名前解決後の IPv6 アドレスを取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべての IP アドレスからランダムなアドレス)。
- (void)getRandomIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;
/// ドメインの IPv4 情報を事前解決します。これはプログラムの開始時に呼び出すことができます。解決結果はキャッシュに保存され、後続のドメイン名前解決を高速化します。
/// @param domainArray ドメイン名の配列。
/// @param complete 解決完了後のコールバック。
- (void)preloadIpv4Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;
/// ドメインの IPv6 情報を事前解決します。これはプログラムの開始時に呼び出すことができます。解決結果はキャッシュに保存され、後続のドメイン名前解決を高速化します。
/// @param domainArray ドメイン名の配列。
/// @param complete 解決完了後のコールバック。
- (void)preloadIpv6Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;
/// キャッシュから IPv4 名前解決結果を直接、待機せずに取得します。
/// キャッシュがない場合は nil を返します。キャッシュがあり、enable が YES に設定されている場合、キャッシュデータを返し、データが期限切れの場合はドメイン名を非同期で解決してキャッシュを更新します。キャッシュがあり、enable が NO に設定されている場合、キャッシュが期限切れのときに nil を返し、ドメイン名を非同期で解決してキャッシュを更新します。
/// @param domain ドメイン名。
/// @param enable 期限切れの IP アドレスを返すことを許可するかどうかを指定します。
- (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;
/// キャッシュから IPv6 名前解決結果を直接、待機せずに取得します。
/// キャッシュがない場合は nil を返します。キャッシュがあり、enable が YES に設定されている場合、キャッシュデータを返し、データが期限切れの場合はドメイン名を非同期で解決してキャッシュを更新します。キャッシュがあり、enable が NO に設定されている場合、キャッシュが期限切れのときに nil を返し、ドメイン名を非同期で解決してキャッシュを更新します。
/// @param domain ドメイン名。
/// @param enable 期限切れの IP アドレスを返すことを許可するかどうかを指定します。
- (NSArray<NSString *> *)getIpv6ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;
///統計情報を収集します。
-(NSArray *)getRequestReportInfo;API 使用例
1. 基本情報の設定
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// アプリケーション起動後のカスタマイズのためのオーバーライドポイント。
// 固有の初期化メソッド
DNSResolver *resolver = [DNSResolver share];
//setAccountId:@"******": アスタリスクの内容を、コンソールの [アクセス設定] ページのアカウント ID に置き換えてください。
//andAccessKeyId:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey ID に置き換えてください。
//andAccesskeySecret:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey Secret に置き換えてください。
[resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
// 期限切れキャッシュの自動更新対象ドメインを指定します。配列は最大 10 個のドメイン名に制限されます。
[resolver setKeepAliveDomains:@[@"user_specified_domain_1",@"user_specified_domain_2"]];
// 後で解決が必要になる可能性のあるドメインをプリロードし、解決結果を事前に取得してキャッシュに保存します。
[resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
// すべてのドメインがプリロードされました。
}];
return YES;
}2. ドメイン名前解決 API
SDK は複数のドメイン名前解決メソッドを提供しており、DNSResolver.h ヘッダーファイルで確認できます。次の例では、ネットワーク環境 (IPv4 のみ、IPv6 のみ、IPv4 と IPv6 のデュアルスタック) を自動的に区別する名前解決メソッドについて説明します。
API 宣言:
/// ドメイン名前解決後の IP アドレスの配列を取得します。ネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動検出し、現在のネットワークに適した IP アドレスを取得します。
/// キャッシュが有効な場合、キャッシュからのデータ返却を優先します。キャッシュがない、またはキャッシュが期限切れの場合、ネットワークリクエストを通じて対応する IP アドレスを取得します。キャッシュが有効でない場合、直接ネットワークリクエストを通じて対応する IP アドレスを取得します。
/// @param domain ドメイン名。
/// @param complete コールバック (すべての IP アドレス)。
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;API 呼び出し例:
[[DNSResolver share] getIpsDataWithDomain:@"www.taobao.com" complete:^(NSArray<NSString *> *dataArray) {
// dataArray はドメイン名 www.taobao.com の IP アドレスの配列です。
if (dataArray.count > 0) {
//TODO: URL 接続に IP アドレスを使用します。
}
}];3. キャッシュから直接名前解決結果を取得
API 宣言:
/// ネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) を自動検出し、現在のネットワークに適した IP アドレスの配列をキャッシュから直接、待機せずに取得します。
/// キャッシュがない場合は nil を返します。キャッシュがあり、enable が YES に設定されている場合、キャッシュデータを返し、データが期限切れの場合はドメイン名を非同期で解決してキャッシュを更新します。キャッシュがあり、enable が NO に設定されている場合、キャッシュが期限切れのときに nil を返し、ドメイン名を非同期で解決してキャッシュを更新します。
/// @param domain ドメイン名。
/// @param enable 期限切れの IP アドレスを返すことを許可するかどうかを指定します。
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;呼び出し例:
NSArray *result = [[DNSResolver share] getIpsByCacheWithDomain:@"domain_name" andExpiredIPEnabled:YES];
// キャッシュされた結果を取得します。
if (result.count > 0) {
//TODO: URL 接続に IP アドレスを使用します。
}注意:キャッシュから直接結果を取得する方が高速です。ただし、キャッシュがない場合、またはキャッシュされた名前解決結果が期限切れで enable が NO に設定されている場合、結果は nil になります。
4. キャッシュの削除
API 宣言:
/// hostArray はキャッシュからクリアするホストドメイン名の配列です。すべてのデータをクリアするには、nil または空の配列を渡します。
-(void)clearHostCache:(NSArray <NSString *>*)hostArray;サンプルコード:
[[DNSResolver share] clearHostCache:@[@"domain 1", @"domain 2"]];5. 統計情報収集
インターフェース宣言:
///統計情報収集
-(NSArray *)getRequestReportInfo;サンプルコード:
NSArray *array = [[DNSResolver share] getRequestReportInfo];データフォーマット:
(
{
avgRtt = "1"; // 平均ドメイン解決時間 (ms)
cacheDnsNum = 0; // キャッシュヒット数
domain = "www.taobao.com"; // 解決中のドメイン名
gobackLocaldnsNum = 0; // LocalDNS にダウングレードした回数
localErro = 0; // LocalDNS の解決失敗回数
maxRtt = "60"; // 最大ドメイン解決時間 (ms)
noPermissionErro = 0; // ユーザー認証失敗回数
noResponseErro = 0; // 応答なしのリクエストタイムアウト回数
requestPDnsNum = 1; // 再帰的クエリの数
sp = "China Mobile"; // ISP 名
successNum = 1; // 解決成功回数
timeoutErro = 0; // ネットワークタイムアウトエラーの数
type = 28; // IP タイプ、1 は IPv4、28 は IPv6 を表す
urlParameterErro = 0; // リクエストパラメーターのフォーマットエラー数
urlPathErro = 0; // URL エラー数
}
......
);ドメイン名前解決のベストプラクティス
事前解決と期限切れ応答の許可を組み合わせて、最適なパフォーマンスを実現します。
高いネットワークパフォーマンスが要求されるシナリオでは、事前解決と期限切れ応答の許可戦略を組み合わせることで、DNS 名前解決の速度を大幅に向上させ、ゼロレイテンシーでの解決さえも実現できます。
SDK の組み込みキャッシュメカニズムのおかげで、事前解決が完了した後、そのドメインの後続の名前解決リクエストは直接キャッシュにヒットします。これにより、ネットワークのラウンドトリップが回避され、ユーザーエクスペリエンスが大幅に最適化されます。
1. 事前解決
キャッシュを有効にし、主要なドメイン名を事前解決します。アプリの起動時にこれを行うことを推奨します。
AppDelegate の application:didFinishLaunchingWithOptions: メソッドで、ビジネスで使用するドメイン名を事前解決し、結果をローカルメモリにキャッシュします。
1. IPv4 のみをサポートするシナリオ
//********IPv4 のみをサポートするシナリオ*******
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
DNSResolver *resolver = [DNSResolver share];
//setAccountId:@"******": アスタリスクの内容を、コンソールの [アクセス設定] ページのアカウント ID に置き換えてください。
//andAccessKeyId:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey ID に置き換えてください。
//andAccesskeySecret:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey Secret に置き換えてください。
[resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
// キャッシュを使用するかどうかを指定します。デフォルト値は YES です。
resolver.cacheEnable = YES;
// 後で解決が必要になる可能性のあるドメインをプリロードします。これにより、ドメインの IPv4 情報が事前解決されます。
[resolver preloadIpv4Domains:@[@"domain1", @"domain2", @"domain3"] complete:^{
// すべてのドメインがプリロードされました。
}];
return YES;
}2. IPv6 をサポートする必要があるシナリオ
//********IPv6 をサポートする必要があるシナリオ*******
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
DNSResolver *resolver = [DNSResolver share];
//setAccountId:@"******": アスタリスクの内容を、コンソールの [アクセス設定] ページのアカウント ID に置き換えてください。
//andAccessKeyId:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey ID に置き換えてください。
//andAccesskeySecret:@"********": アスタリスクの内容を、コンソールの [アクセス設定] ページで作成したキーの AccessKey Secret に置き換えてください。
[resolver setAccountId:@"******" andAccessKeyId:@"********" andAccesskeySecret:@"********"];
// キャッシュを使用するかどうかを指定します。デフォルト値は YES です。
resolver.cacheEnable = YES;
// IPv6 ネットワークを使用してドメイン名を解決するかどうかを指定します。デフォルト値は NO です。
resolver.ipv6Enable = YES;
// IP アドレスのプロービングを有効にするかどうかを指定します。デフォルト値は NO です。
resolver.speedTestEnable = YES;
// 後で解決が必要になる可能性のあるドメインをプリロードします。これにより、ネットワーク環境 (IPv4 のみ、IPv6 のみ、またはデュアルスタック) が自動的に検出され、現在のネットワークに適した IP アドレスが解決されます。
[resolver preloadDomains:@[@"domain1", @"domain2", @"domain3"] complete:^{
// すべてのドメインがプリロードされました。
}];
return YES;
}2. 期限切れ応答の許可
名前解決時には、キャッシュの使用を優先し、期限切れの IP アドレスの返却を許可します。ネットワークリクエストを開始する前に、まずキャッシュから IP アドレスを取得し、期限切れだがまだ有効なキャッシュレコードの使用を許可します (andExpiredIPEnabled:YES)。これにより、TTL が経過していても、キャッシュがクリアされていない限り、すぐに結果を返すことができ、待機時間ゼロの解決が実現します。
1. IPv4 のみをサポートするシナリオ
//********IPv4 のみをサポートするシナリオ*******
__weak typeof(self) ws = self;
// キャッシュからの IP 取得を優先します (ExpiredIPEnabled は YES で、期限切れだが利用可能なレコードの返却を許可します)。
NSArray<NSString *> *cachedIPs = [[DNSResolver share] getIpv4ByCacheWithDomain:domain andExpiredIPEnabled:YES];
if (cachedIPs && cachedIPs.count > 0) {
NSString *ip = cachedIPs.firstObject;
NSLog(@"キャッシュヒットが速いです。ドメイン %@ は IP: %@ に解決されました", domain, ip);
[self requestWithIP:ip domain:domain]; // IP を使用して直接接続します。
} else {
// キャッシュミスの場合、非同期解決を開始します。
[[DNSResolver share] getIpv4DataWithDomain:domain complete:^(NSArray<NSString *> *resolvedIPs) {
if (resolvedIPs && resolvedIPs.count > 0) {
NSString *ip = resolvedIPs.firstObject;
NSLog(@"非同期解決が完了しました。ドメイン %@ は IP: %@ に解決されました", domain, ip);
[ws requestWithIP:ip domain:domain]; // IP を使用して直接接続します。
} else {
NSLog(@"ドメイン名の解決に失敗しました。元のドメイン名にフォールバックします。");
[ws requestWithIP:domain domain:domain]; // フォールバック:元のドメイン名を使用します。
}
}];
}2. IPv6 をサポートする必要があるシナリオ
//********IPv6 をサポートする必要があるシナリオ*******
__weak typeof(self) ws = self;
// キャッシュからの IP 取得を優先します (ExpiredIPEnabled は YES で、期限切れだが利用可能なレコードの返却を許可します)。
NSArray<NSString *> *cachedIPs = [[DNSResolver share] getIpsByCacheWithDomain:domain andExpiredIPEnabled:YES];
if (cachedIPs && cachedIPs.count > 0) {
NSString *ip = cachedIPs.firstObject;
NSLog(@"キャッシュヒットが速いです。ドメイン %@ は IP: %@ に解決されました", domain, ip);
[self requestWithIP:ip domain:domain]; // IP を使用して直接接続します。
} else {
// キャッシュミスの場合、非同期解決を開始します。
[[DNSResolver share] getIpsDataWithDomain:domain complete:^(NSArray<NSString *> *resolvedIPs) {
if (resolvedIPs && resolvedIPs.count > 0) {
NSString *ip = resolvedIPs.firstObject;
NSLog(@"非同期解決が完了しました。ドメイン %@ は IP: %@ に解決されました", domain, ip);
[ws requestWithIP:ip domain:domain]; // IP を使用して直接接続します。
} else {
NSLog(@"ドメイン名の解決に失敗しました。元のドメイン名にフォールバックします。");
[ws requestWithIP:domain domain:domain]; // フォールバック:元のドメイン名を使用します。
}
}];
}注意事項
pdns-sdk-ios.frameworkは、最小 iOS バージョン 9.0 をサポートします。HTTP プロトコルを使用してリクエストを行う場合、
Info.plistでApp Transport Security Settings->Allow Arbitrary LoadsをYESに設定する必要があります。HTTPDNS を介してドメイン名の IP アドレスを取得した後、クライアントはこの IP アドレスを使用してサービスリクエストを送信できます。HTTP リクエストヘッダーの Host フィールドは、元のドメイン名に設定する必要があります。
例:
// ip は元のドメイン名から解決された IP アドレスです。 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", ip]]; NSMutableURLRequest *mutableReq = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval: 10]; // ホストを設定します。 [mutableReq setValue:@"original_domain_name" forHTTPHeaderField:@"host"];サービスが正しく実行されるように、SDK がドメイン名の IP アドレスを取得できなかった場合は、フォールバックとして元のドメイン名を使用してリクエストを行ってください。次のコードは例です。
NSArray *array = [[DNSResolver share] getIpsByCacheWithDomain:@"original_domain_name" andExpiredIPEnabled:YES]; if (array && array.count >0 && array.firstObject.length > 0) { // URL のホストを API リクエスト用の IP アドレスに置き換えます。 }else{ // フォールバック処理を追加します (API リクエストに元の URL を使用します)。 }中間 HTTP プロキシが存在する場合、クライアントが開始するリクエストのリクエスト行は絶対パス URL を使用します。HTTPDNS を有効にして IP ベースの URL でアクセスすると、中間プロキシは IP 情報を識別し、それを実際のホスト情報としてターゲットサーバーに渡します。この場合、ターゲットサーバーは実際のホスト情報を含まない HTTP リクエストを処理できません。現在のデバイスでネットワークプロキシが有効になっているかどうかを確認することをお勧めします。プロキシが有効な場合は、HTTPDNS を使用してドメイン名前解決を行わないでください。
オンプレミス DNS
v2.3.0 以降、HTTPDNS iOS SDK はプライベートデプロイメント向けのオンプレミス DNS をサポートします。
オンプレミス DNS モードは、金融、政府、大手インターネット企業など、データコンプライアンスとカスタム名前解決ポリシーに対する要件が高いシナリオに適しています。SDK は、パブリッククラウド DNS のみ、オンプレミス DNS のみ、およびパブリッククラウド DNS とオンプレミス DNS が相互にバックアップとして機能するプライマリ/バックアップハイブリッドモードという 4 つの典型的なデプロイモードをサポートし、さまざまなビジネスアーキテクチャに柔軟に対応します。
コア機能
プライベートデプロイメントのサポート:IPv4 または IPv6 アドレス、またはホストドメイン名を使用して、オンプレミス DNS サーバーのエンドポイントを設定することをサポートします。
双方向認証:顧客固有の
accessKeyIdとaccessKeySecretを使用してリクエストに署名し、通信のセキュリティを確保します。サーキットブレイクとヘルスチェック:オンプレミス DNS ノードが 3 回以上連続して失敗した場合、自動的にサーキットをブレイクします。その後、指定された
healthCheckDomainを使用して、1 分ごとにノードの可用性をプローブします。ノードが回復すると、自動的に再度有効になります。証明書検証の制御:TLS 証明書検証の有効/無効をサポートします。本番環境では有効にすることを強く推奨します。
スマートフェイルオーバー:プライマリ DNS (パブリッククラウドまたはオンプレミス) がリクエストの解決に失敗し、指定されたしきい値に達した場合、自動的にバックアップ DNS に切り替わります。これにより、名前解決の高可用性が確保されます。
シームレスな API 互換性:パブリッククラウド DNS またはオンプレミス DNS のどちらを使用しても、名前解決 API の呼び出し方は同じです。ビジネスロジックを変更する必要はありません。
設定
1. パブリッククラウド DNS のみを使用
このモードは、オンプレミス DNS をデプロイしていない標準的な SaaS ユーザー向けです。
DNSResolver *resolver = [DNSResolver share];
[resolver setAccountId:@"******"
andAccessKeyId:@"********"
andAccesskeySecret:@"********"];2. オンプレミス DNS のみを使用 (プライベートデプロイメント)
このモードは、オンプレミス DNS に完全に依存しているお客様向けです。
DNSResolver *resolver = [DNSResolver share];
[resolver setFusionDNSWithIPv4:@[@"1.1.X.X", @"2.2.X.X"]
IPv6:nil
Host:nil
Port:@"443"
HealthCheckDomain:@"check.example.com"
accessKeyId:@"your_fusion_ak"
accesskeySecret:@"your_fusion_sk"];
// オプション:証明書検証を無効にします (テスト環境のみ)。
// [resolver setEnableCertificateValidation:NO];3. パブリッククラウド DNS をプライマリ、オンプレミス DNS をバックアップとして使用
プライマリの Alibaba Cloud パブリック HTTPDNS が失敗した場合、自動的にオンプレミス DNS にフェイルオーバーします。
DNSResolver *resolver = [DNSResolver share];
// プライマリ:パブリッククラウド DNS
[resolver setAccountId:@"******"
andAccessKeyId:@"********"
andAccesskeySecret:@"********"];
// バックアップ:オンプレミス DNS
[resolver setFusionDNSWithIPv4:@[@"1.1.X.X", @"2.2.X.X"]
IPv6:nil
Host:nil
Port:@"443"
HealthCheckDomain:@"check.example.com"
accessKeyId:@"your_fusion_ak"
accesskeySecret:@"your_fusion_sk"];
// オプション:証明書検証を無効にします (テスト環境のみ)。
// [resolver setEnableCertificateValidation:NO];4. オンプレミス DNS をプライマリ、パブリッククラウド DNS をバックアップとして使用
プライマリのオンプレミス DNS が失敗した場合、自動的に Alibaba Cloud パブリック HTTPDNS にフェイルオーバーします。
DNSResolver *resolver = [DNSResolver share];
// プライマリ:オンプレミス DNS
[resolver setFusionDNSWithIPv4:@[@"1.1.X.X", @"2.2.X.X"]
IPv6:nil
Host:nil
Port:@"443"
HealthCheckDomain:@"check.example.com"
accessKeyId:@"your_fusion_ak"
accesskeySecret:@"your_fusion_sk"];
// オプション:証明書検証を無効にします (テスト環境のみ)。
// [resolver setEnableCertificateValidation:NO];
// バックアップ:パブリッククラウド DNS
[resolver setAccountId:@"******"
andAccessKeyId:@"********"
andAccesskeySecret:@"********"];新しいサービス API
プライベートデプロイメントとオンプレミス DNS の高可用性ディザスタリカバリをサポートするために、SDK は以下の 3 つのコア API を追加します。これらの API は、オンプレミス DNS サービスの設定、セキュリティポリシーの制御、および自動プライマリ/バックアップフェイルオーバーの実装に使用されます。
1. オンプレミス DNS サーバーのエンドポイントと認証情報の設定
/** これはプライベートデプロイメント向けのオンプレミス DNS に関連します。パブリック DNS のみを使用する場合は、このメソッドを呼び出さないでください。
*
* オンプレミス DNS サーバーのアドレスと認証情報を設定します。
* お客様はこの API を通じてプライベート DNS サーバーのアドレスと認証情報を渡します。
* SDK はこの情報を使用してリクエストを開始します。
* @param ipv4 IPv4 アドレスの配列 (nil も可)。
* @param ipv6 IPv6 アドレスの配列 (nil も可)。
* @param host ホストドメイン名の配列 (nil も可)。
* @param port サービスポート (例:@"443"。nil の場合はデフォルトが使用されます)。
* @param healthCheckDomain サーキットブレイク後のヘルスチェック用ドメイン名。名前解決サービスが 3 回以上連続して失敗すると、サーキットがブレイクし、サービスの IP アドレスは healthCheck 状態になります。後続のリクエストではこのサービスは使用されません。タイマーが 1 分ごとにこの healthCheckDomain をプローブし、サービスが利用可能かどうかを確認します。プローブが成功すると、サービスの状態は alive に復元され、将来のリクエストで使用できるようになります。
* @param accessKeyId お客様のプライベート accessKeyId (認証用)。
* @param accesskeySecret お客様のプライベート accesskeySecret (認証用)。
*/
- (void)setFusionDNSWithIPv4:(NSArray<NSString *> * _Nullable)ipv4
IPv6:(NSArray<NSString *> * _Nullable)ipv6
Host:(NSArray<NSString *> * _Nullable)host
Port:(NSString * _Nullable)port
HealthCheckDomain:(NSString * _Nonnull)healthCheckDomain
accessKeyId:(NSString * _Nonnull)accessKeyId
accesskeySecret:(NSString * _Nonnull)accesskeySecret;2. オンプレミス DNS の TLS 証明書検証の制御
/** これはプライベートデプロイメント向けのオンプレミス DNS に関連します。パブリック DNS のみを使用する場合は、このメソッドを呼び出さないでください。
*
* オンプレミス DNS の証明書検証を有効にするかどうかを指定します (デフォルトは YES)。サーバーにドメイン証明書と IP 証明書が設定されていない場合、テスト用にこれを NO に設定できます。本番環境では、セキュリティリスクを避けるためにこれを YES に設定することを強く推奨します。
* @param enable YES で有効 (デフォルト)、NO で無効。
*/
- (void)setEnableCertificateValidation:(BOOL)enable;3. プライマリ/バックアップ DNS の自動フェイルオーバーしきい値の設定
/** パブリッククラウド DNS とオンプレミス DNS の両方が設定されている場合、プライマリ DNS が何回失敗したら自動的にバックアップ DNS にフェイルオーバーするかを設定します。1 種類の DNS のみが設定されている場合は、このメソッドを呼び出さないでください。
*
* プライマリ DNS が何回失敗したら自動的にバックアップ DNS にフェイルオーバーするかを設定します。1 種類の DNS のみが設定されている場合は、このメソッドを呼び出さないでください。
* @param fallbackThreshold 失敗回数 (パブリッククラウド DNS がプライマリの場合はデフォルト 4、オンプレミス DNS がプライマリの場合はデフォルト 2)。
* 有効範囲は [0-4] です。値が 0 の場合は即座にフェイルオーバーが発生します。最大値は 4 です。
*/
- (void)setFallbackThreshold:(NSInteger)fallbackThreshold;