如何使用阿里云公共DNSAndroidSDK |
您所在的位置:网站首页 › 阿里云公共dns › 如何使用阿里云公共DNSAndroidSDK |
1.概述 阿里云公共DNS SDK是阿里云面向广大移动开发者提供DNS域名解析服务的开发工具包。 开发者利用本SDK,可以在自己的Android APP中轻松接入阿里云公共DNS,解决域名解析异常的问题,低成本实现域名解析精准调度。您可以参考Demo示例工程源码了解如何使用本SDK。 SDK当前版本封装了阿里公共DNS的DoH JSON API,提供Java函数接口给Android APP进行域名解析,并且提供了基于TTL和LRU策略的高效域名缓存功能。在公共DNS原有功能的基础上,SDK还可以为用户带来以下优势: 简单易用: 用户仅需集成我们提供的SDK,便可接入阿里云公共DNS业务。接入方法简单易用,为用户提供更为轻松便捷的解析服务。 零延迟: SDK内部实现了LRU的缓存机制,将每次域名解析后的IP缓存到本地;并且主动更新TTL过期缓存,保证缓存及时有效,从而帮助用户达到域名解析零延迟的效果。 2.如何使用SDK2.1 jar集成 您需先在控制台注册自己的应用,获取应用的唯一标识Account ID 然后通过控制台的链接获取阿里公共DNS SDK 获取到的SDK的alidns_android_sdk.jar集成到自己工程项目libs目录中即可轻松使用 2.2 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.1.3' implementation 'com.google.code.gson:gson:2.8.5' }2.3 应用程序初始化 public class DnsCacheApplication extends Application{ private String accountID="***"; //设置您在控制台接入sdk的accountId private static final String TAOBAO_HOST_NAME = "www.taobao.com";//请替换为您要预加载的域名 private static final String ALIYUN_HOST_NAME = "www.aliyun.com"; //请替换为您要预加载的域名 private static final int CACHE_MAX_NUMBER=100; //设置缓存域名的最大个数,默认为100 private static final int MAX_NEGATIVE_CACHE = 30; //设置否定缓存的最大TTL时间,默认为30秒 private static final int MAX_TTL_CACHE = 1 * 60 * 60; //设置缓存的最大TTL时间,默认为3600秒 @Override public void onCreate() { super.onCreate(); DNSResolver.Init(this, accountID); //设置控制台接入sdk的accountId DNSResolver.setAccessKeySecret(""); //设置控制台接入sdk的accessKeySecret DNSResolver.setAccessKeyId(""); //设置控制台接入sdk的accessKeyId DNSResolver.setEnableShort(false); //设置是否开启short模式,默认不开启 DNSResolver.setEnableIPv6(false); //设置是否开启IPV6的访问模式,默认不开启 DNSResolver.setEnableCache(true); //设置是否开启使用缓存,默认开启 DNSResolver.setEnableSpeedTest(false); //设置是否开启IP测速,默认不开启 DNSResolver.setEnableSchedulePrefetch(true); //设置是否开启定时主动更新过期缓存,默认为开启 DNSResolver.setMaxTtlCache(MAX_TTL_CACHE); //设置缓存的最大TTL时间,默认为3600秒 DNSResolver.setSpeedPort(DNSResolver.PORT_80); //设置ip测量socket检测的端口号,默认80端口 DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE); //设置否定缓存的最大TTL时间,默认为30秒 DNSResolver.setSchemaType(DNSResolver.HTTPS); //设置访问http还是https模式 DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); //设置缓存域名的最大个数,默认为100 DNSResolver.getInstance().preLoadDomains(new String[]{TAOBAO_HOST_NAME,ALIYUN_HOST_NAME}); //设置域名预先解析,将预加载域名替换为您希望使用阿里DNS解析的域名 } }接入阿里公共DNS SDK时建议在Application子类里集成。 说明DNSResolver为阿里公共DNS SDK的核心类,其内部封装了阿里公共DNS提供的DoH JSON API,将用户的目标域名解析成为对应的IP。 另外,Android工程在使用SDK时,需要保证提供以下访问权限的配置: 注意事项: 1). Android 9.0 发送HTTP网络请求会报cleartext HTTP traffic no permitted异常 原因:从Android9.0(API 28)开始,Android默认禁止明文访问网络只允许使用https url访问。 解决方案 在应用的AndroidManifest.xml文件的中添加代码: android:usesCleartextTraffic="true" 2). Android9.0会报异常:Didn't find class BasicHttpParams。 原因:Apache Http客户端弃用 。 因为早在Android 6.0中,谷歌取消了对Apache Http客户端的支持。从Android 9.0开始,org.apache.http.legacy从bootclasspath中删除。 该修改对于大多数 taskVersion<9.0的应用没有影响,对所有taskVersion>9.0的应用,如果继续使用Apache Http接口或者引用的lib包中用到该接口时,都会出现Apache Http接口找不到的异常。 解决方案 在应用的AndroidManifest.xml文件的中添加: 3). 本SDK从2.0开始支持设置鉴权认证功能,来保障用户身份安全,不被第三方未授权者盗用。 如果用户不设置以下参数则不会开启鉴权功能,若要开启鉴权功能,请参考产品鉴权文档在控制台上创建 AccessKey ID和AccessKey Secret,可以通过以下2种方式添加配置: 在应用的AndroidManifest.xml文件中添加以下配置 在应用接入SDK初始化时设置参数: DNSResolver.setAccessKeySecret(""); //设置控制台接入sdk的accessKeySecret DNSResolver.setAccessKeyId(""); //设置控制台接入sdk的accessKeyId 说明以上两种配置鉴权认证方式,开发者可根据实际应用场景任选其一。当配置了其中的一种则无需再重复配置另外一种方式。 4). 为了更好的使用本SDK,建议您在编译APP时将JDK的版本设置为1.8。 2.4.1 服务初始化 阿里公共DNS SDK是通过DNSResolver类封装了阿里公共DNS服务请求和本地缓存实现的。用户通过DNSResolver.Init(this,accountID)初始化,即可统一接入阿里公共DNS服务。(accountID为用户在控制台注册时,server端自动生成用户唯一标识) 2.4.2 设置预解析域名 在您初始化程序时,可以选择性地预先向阿里公共DNS SDK中注册您后续可能会使用到的域名,以便SDK提前解析,减少后续解析域名时请求的时延。调用以下方法设置预解析域名: 指定预加载IPV6或IPV4域名解析 //设置域名预先解析,将预加载域名替换为您希望使用阿里DNS解析的域名 DNSResolver.getInstance().preLoadDomains(DNSResolver.QTYPE_IPV4,new String[]{...}) DNSResolver.QTYPE_IPV4 预取域名解析的IPV4记录类型 DNSResolver.QTYPE_IPV6 预取域名解析的IPV6记录类型根据当前网络自动匹配预加载IPV6或IPV4域名解析 DNSResolver.getInstance().preLoadDomains(domains)重要预解析接口设置的同时会实时触发异步网络请求,应该在代码逻辑上确保调用预解析接口时,已经进行了必备的初始化设置。 2.4.3 设置是否使用服务端IPV6地址 阿里公共DNS服务支持IPV4、IPV6双栈地址访问,通过DNSResolver.setEnableIPv6(boolean enable)方法来设置是否使用服务端IPV6地址。当设置为true表示使用IPV6的IP地址访问服务端接口,false表示使用IPV4的IP地址访问服务端接口。如不显式设置,默认为使用IPV4地址访问。另外当设置为IPV6地址时,当访问阿里公共DNS服务不通时则自动切换为IPV4地址,并且支持重试3次策略。 2.4.4 设置是否开启Short模式 阿里公共DNS的DoH JSON API返回数据类型分为全量JSON和简要IP数组格式,可以通过调用DNSResolver.setEnableShort (boolean enable)来开启或关闭short模式。如不显式设置,默认为关闭short模式。 如下方式: DNSResolver.setEnableShort (true); //默认值是false,该参数用户可以不需设置,不设置则默认为false。重要short模式为SDK调用阿里公共DNS服务返回的比较简单IP数组,可以减少回复的数据量,适用于对网络流量敏感的场景。 2.4.5 设置缓存的最大个数 DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER); //设置缓存的最大个数,默认为100用户可以自定义最大count的值。 2.4.6设置缓存的最大TTL时间 DNSResolver.setMaxTtlCache(MAX_TTL_CACHE);//设置缓存的最大TTL时间,默认为3600秒2.4.7 设置访问服务端协议 DNSResolver.setSchemaType(DNSResolver.HTTPS); 默认访问为http的模式。DNSResolver.HTTP,以HTTP协议访问服务端接口 DNSResolver.HTTPS,以HTTPS协议访问服务端接口 2.4.8 设置是否开启使用缓存 DNSResolver.setEnableCache(true); //默认开启使用缓存用户可以设置是否开启使用缓存功能(true为开启缓存功能,false为关闭缓存功能) 2.4.9 设置是否开启IP测速 DNSResolver.setEnableSpeedTest(false); //默认不开启IP测速用户可以设置是否开启IP测速(true为开启IP测速功能,false为关闭IP测速功能) 2.4.10 设置IP测速socket监测的端口号 DNSResolver.setSpeedPort(DNSResolver.PORT_80)用户可以设置IP测速基于socket监测的端口号,默认为80 2.4.11 设置是否开启依据ISP网络区分域名缓存 DNSResolver.setIspEnable(true);//是否开启依据ISP网络区分域名缓存设置是否开启依据ISP网络区分域名缓存。如果开启,则在不同网络环境下域名缓存数据分别存储互不影响。如果不开启,则不同网络下使用同一份域名缓存数据 2.4.12 设置否定缓存的最大TTL时间 DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);//设置否定缓存的最大TTL时间,默认为30秒用户可以根据自身的需求设置否定缓存的最大TTL时间 2.4.13 设置鉴权认证AccessKeySecret、AccessKeyId参数 DNSResolver.setAccessKeySecret(""); //设置控制台接入sdk的accessKeySecret DNSResolver.setAccessKeyId(""); //设置控制台接入sdk的accessKeyId2.4.14 设置是否开启定时主动更新过期缓存 本SDK在缓存功能已开启的情况下,可设置开启定时主动更新过期缓存功能。如果该功能开启后,SDK会每分钟主动更新过期缓存一次,可以有效保障用户缓存数据得到及时更新。但可能会带来域名解析次数和客户端网络流量消耗的增加。 DNSResolver.setEnableSchedulePrefetch(true); // 设置是否开启定时主动更新过期缓存,默认为开启3.反混淆配置 -keep class com.alibaba.pdns.** {*;}4.服务API /** * 通过自动感知当前网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)获取该域名的解析数据 * * @param host 用户所要解析的域名 * @return 返回根据当前网络环境下的最优IP数组 */ public String[] getIpsByHost(String host) /** * 通过自动感知当前网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)预加载域名解析 * * @param domains 预加载解析的域名 */ public void preLoadDomains(final String[] domains) /** * 通过自动感知当前网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)从缓存中获取该域名解析后的IP数组 * 如果缓存没有,该方法是先直接返回null,然后同时进行异步查询,最后将查询到的数据存入缓存中 * * @param host 查询的host 例如(www.taobao.com) * @param isAllowExp 是否允许返回已过期域名的解析数据 * @return 获取缓存中对应host解析后的IP数组 */ public String[] getIpsByHostFromCache(String host, boolean isAllowExp) /** * 获取url对应IPv4记录的DomainInfo对象数组 * * @param url例如(http://www.taobao.com) * @return目标url对应IPV4类型的DomainInfo对象数组 */ public DomainInfo[] getIPsV4DInfoByUrl(String url) 注意:DomainInfo对象中的url为替换host为IP拼接后的url,用户不需再手动url的替换拼接。 /** * 获取url对应IPv6记录的DomainInfo对象数组 * * @param url 例如(http://m.taobao.com) * @return 目标url对应IPV6类型的DomainInfo对象数组 */ public DomainInfo[] getIPsV6DInfoByUrl(String url) /** * 获取url对应IPV4记录的DomainInfo对象 * * @param url 例如(http://m.taobao.com) * @return 目标url对应IPV4类型的DomainInfo对象集合中随机的一个 */ public DomainInfo getIPV4DInfoByUrl(String url) /** * 获取url对应IPV6记录的DomainInfo对象 * * @param url 例如(http://www.taobao.com) * @return 目标url对应IPV6类型的DomainInfo对象集合中随机的一个 */ public DomainInfo getIPV6DInfoByUrl(String url) 说明:返回的domainInfo对象,主要是封装了如下属性 /** * id访问域名自增的id编号 */ public String id = null; /** * 可以直接使用的url 已经替换了host为ip后的url */ public String url = null; /** * 需要设置到http header里面的目标服务名称 */ public String host = ""; /** * 返回的内容体 */ public String data = null; /** * 开始请求的时间 */ public String startTime = null; /** * 请求结束的时间,如果请求超时,该值为null */ public String stopTime = null; /** * server返回的状态值200 \ 404 \ 500等 */ public String code = null; /** * 获取hostName对应IPV4记录数组 * @param hostName例如(www.taobao.com) * @return 返回目标hostName对应的IPV4地址的数组 */ public String[] getIPsV4ByHost(String hostName) /** * 获取hostName对应IPV6记录数组 * @param hostName例如(www.taobao.com) * @return 返回目标hostName对应的IPV6地址的数组 */ public String[] getIPsV6ByHost(String hostName) /** * 获取hostName对应IPV4记录 * @param hostName例如(www.taobao.com) * @return 返回目标hostName对应的IPV4地址集合中的一个随机IPV4地址,当开启测速返回一个最优IPV4地址 */ public String getIPV4ByHost(String hostName) /** * 获取hostName对应IPV6记录 * @param hostName例如(www.taobao.com) * @return 返回目标hostName对应的IPV6地址集合中的一个随机IPV6地址,当开启测速返回一个最优IPV6地址 */ public String getIPV6ByHost(String hostName) /** * 从缓存中获取该域名解析后的IPV4记录类型的IP数组 * 如果缓存没有,该方法是先直接返回null,然后同时进行异步查询,最后将查询到的数据存入缓存中 * * @param host 查询的host 例如(www.taobao.com) * @param isAllowExp 是否允许返回已过期域名的解析数据 * @return 获取缓存中对应host解析后的IPV4记录类型的IP数组 */ private String[] getIpv4ByHostFromCache(String host , boolean isAllowExp) /** * 从缓存中获取该域名解析后的IPV6记录类型的IP数组 * 如果缓存没有,该方法是先直接返回null,然后同时进行异步查询,最后将查询到的数据存入缓存中 * * @param host 查询的host 例如(www.taobao.com) * @param isAllowExp 是否允许返回已过期域名的解析数据 * @return 获取缓存中对应host解析后的IPV6记录类型的IP数组 */ private String[] getIpv6ByHostFromCache(String host , boolean isAllowExp) /** * 预加载域名解析 * * @param qType 预加载解析IPV4还是IPV6 * @param domains 预加载解析的域名 */ public void preLoadDomains(String qType, final String[] domains) /** * 获取请求阿里公共DNS成功失败统计信息 * * @return 所有的域名解析统计信息Json数组字符串 */ public String getRequestReportInfo() 5.SDK API使用示例URl:传进来的访问地址,例如:http://www.taobao.com。 String hostname = "www.taobao.com"; String url = "http://www.taobao.com";5.1 获取当前网络环境下的最优IP数据: String[] ip = DNSResolver.getInstance().getIpsByHost(hostname); //获取当前网络下的最优域名解析IP5.2 根据当前网络环境预加载域名解析: DNSResolver.getInstance().preLoadDomains(domains) //设置域名预先解析,将预加载域名替换为您希望使用阿里DNS解析的域名5.3 根据当前网络环境读取缓存中的域名解析数据: String[] ip = DNSResolver.getInstance().getIpsByHostFromCache(hostname,true);//获取当前网络环境缓存中的域名解析数据5.4 获得IPv4地址: String IPV4 = DNSResolver.getInstance().getIPV4ByHost(hostname); //获取IPV4的域名解析5.5 获得IPv6地址: String IPV6 = DNSResolver.getInstance().getIPV6ByHost(hostname) //获取IPV6的域名解析5.6 从缓存中获取ipv4解析地址 String[] IPV4 = DNSResolver.getInstance().getIpv4ByHostFromCache(hostname , true) //获取缓存里IPV4的域名解析5.7 从缓存中获取ipv6解析地址 String[] IPV6 = DNSResolver.getInstance().getIpv6ByHostFromCache(hostname , true) //获取缓存里IPV6的域名解析5.8 获得URL对应的DomainInfo对象: DomainInfo dinfo = DNSResolver.getInstance().getIPV4DInfoByUrl(url); //获取替换的URL5.9 获取请求阿里DNS成功失败统计信息 String reportInfo = DNSResolver.getInstance().getRequestReportInfo();//获取成功失败统计信息所有的域名解析的统计信息JSON字符串数组中的字段含义描述如下: ![]() 请求阿里公共DNS域名解析统计数据是以网络环境+域名+请求类型为统计维度 6.示例: public class MainActivity extends AppCompatActivity { private Button button; private TextView tvInfo; private TextView tvResult; private String hostUrl = "http://www.taobao.com"; //请替换为您需要解析hostUrl private String hostName = "www.taobao.com"; //请替换为您需要解析hostName 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() { //调用阿里公共sdk里的getIpsByHostFromCache方法获得目标域名解析后的IP String ip = DNSResolver.getInstance().getIpsByHostFromCache(hostName,true); tvInfo.setText("您解析域名的IP是:"+ ip); //调用阿里公共sdk里getIPV4DInfoByUr获取目标域名解析后的domainInfo对象中的URL,该URL为已替换原来url中host为IP的url 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 accountID = "****"; //可以更换成您的accountID private static final String TAOBAO_HOST_NAME = "www.taobao.com";//请替换为您要预加载的域名 private static final String ALIYUN_HOST_NAME = "www.aliyun.com";//请替换为您要预加载的域名 private static final int CACHE_MAX_NUMBER = 100; //缓存域名的最大个数,默认为100 private static final int MAX_NEGATIVE_CACHE = 30; //设置否定缓存的最大TTL时间,默认为30秒 private static final int MAX_TTL_CACHE = 1 * 60 * 60; //设置缓存的最大TTL时间,默认为3600秒 @Override public void onCreate() { super.onCreate(); DNSResolver.Init(this, accountID);//设置控制台接入sdk的accountId DNSResolver.setAccessKeySecret("");//设置控制台接入sdk的accessKeySecret DNSResolver.setAccessKeyId(""); //设置控制台接入sdk的accessKeyId DNSResolver.setEnableShort(false);//设置是否开启short模式 DNSResolver.setEnableIPv6(false);//设置是否开启IPV6的访问模式 DNSResolver.setEnableCache(true);//设置是否开启使用缓存 DNSResolver.setEnableSpeedTest(false);/设置是否开启IP测速 DNSResolver.setEnableSchedulePrefetch(true); // 设置是否开启定时主动更新过期缓存,默认为开启 DNSResolver.setIspEnable(true);//设置是否开启依据ISP网络区分域名缓存 DNSResolver.setMaxTtlCache(MAX_TTL_CACHE); //设置缓存的最大TTL时间,默认为3600秒 DNSResolver.setMaxNegativeCache(MAX_NEGATIVE_CACHE);//设置否定缓存的最大TTL时间,默认为30秒 DNSResolver.setSchemaType(DNSResolver.HTTPS);//设置访问http还是https模式 DNSResolver.setSpeedPort(DNSResolver.PORT_80);//设置ip测量socket检测的端口号,默认80端口 DNSResolver.getInstance().setMaxCacheSize(CACHE_MAX_NUMBER);//设置缓存域名的最大个数,默认为100 DNSResolver.getInstance().preLoadDomains(new String[]{TAOBAO_HOST_NAME,ALIYUN_HOST_NAME });//设置域名预先解析,预加载域名替换为您希望使用阿里DNS解析的域名 } }注意事项通过阿里公共DNS获得域名的IP地址后,客户端可以使用这个IP发送业务请求,HTTP请求头的Host字段需改为原来的域名。 为帮助用户更快使用阿里公共DNS SDK,我们为读者提供Demo程序,读者可以下载到本地作为参考请点击这里,下载Demo程序。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |