通常情况下,做移动开发时,如果要向后台请求数据,都会直接使用TCP通信。但实际上一来HTTP比TCP简单易用多了,二来有很多现有CGI如果要进行改造得花很大功夫。还是会有使用HTTP请求来拉取数据。

在做Android QQ二维码时,扫描到二维码字符串,就是把该字符串用HTTP传给后台,后台解析后返回给客户端,客户端再进行下一步处理。在提交测试后,测试同事发现,在移动网络上,DNS解析会经常失败,导致二维码扫描功能不可用。功能测试不通过,导致无法发布。同时测试喜欢在清空DNS缓存和屏蔽了DNS解析的情况下,二维码解析功能仍然可用。因此这里增加了如下处理:
1. 进入“扫一扫”的界面时,客户端就开始对CGI所在域名进行解析,并把解析结果缓存到本地文件;
2. 发起CGI请求时,还是使用原域名进行请求,如果DNS解析失败,则用第一步缓存的IP替换掉CGI中的域名再发起一次请求。

由于国内有好几个网络运营商,公司在不同的网络环境都有不一样的出口IP,因此选择最近的IP才能快速访问CGI。所以缓存域名结果时,需要区分网络分别保存。

这样,当用户的手机上至少成功使用了一次二维码扫描时,CGI对应的IP就保存下来了(至少有一个出口IP)。下次访问(同一次登录或者关闭手机QQ后再打开)时,即使DNS解析失败,还是能使用上一次保存的IP进行访问,可能会相应比较慢(用户从A网络切换到了B网络),但起码保证了功能的可用性。

实现起来也不难,Java都有现成的接口了。
主动发起DNS解析只要调用InetAddress的接口即可,把获取到的结果保存到SharedPreferences供下次使用:

然后在HTTP请求出现DNS解析错误的时候,用IP替换掉URL中的域名即可:

这里之所以不直接用上次保存的IP来替换域名进行访问,是因为在正常情况下,进入“扫一扫”的界面时,已经预先对所用域名进行了预解析,如果解析成功,调用openRequest时就不用DNS查询了;而如果预解析失败了,openRequest的时候还能再尝试一次,失败时才使用IP访问。同时,很多用户都会在移动网络和WIFI网络中切换,如果直接用IP替换域名,会出现用户当前是移动网络,而是用的域名IP是在教育网IP(上一次使用的是教育网WIFI)的情况,导致CGI响应变得更慢。

当然,更好的解决方法是:先检测当前用户的网络环境,如果本地保存了对应网络的IP,直接使用IP请求;如果没有,再改用域名来请求。

还有更进阶的方案:第一次登陆时,从服务器拉取一份host列表(每个域名包括各个网络环境的出口IP),把所有HTTP请求的域名都替换成相应IP,这样就能完美解决DNS不可用、DNS解析失败的情况了。之后维护host文件的更新即可。

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2013/10/do-everything-possible-to-speed-up-dns-resolution-speed-web/

  1. 李白 2017 年 3 月 30 日

    找外包,想要稳定靠谱、费用还低的外包商?难!
    怕被坑?上空心www.kxhtml.com 一家100元/页的软件开发云平台!
    在招人,海招海筛、培训,到头来上手还是慢!
    用结果打脸!上空心www.kxhtml.com 一家先看开发结果后付费的平台!
    想创业,有idea?到处找CTO?技术难关攻不破?
    立即上线!上空心www.kxhtml.com 一家开发神速火箭般输出页面的平台!

  2. 乔布尸 2014 年 3 月 24 日

    在我们学校,手机使用wifi,然后代理,在腾讯相关产品扫二维码基本失效,比如微信网页登陆,QQ扫码加扣,使用socket5。必须换回移动网络才能成功。

  3. 廖俊媛 2013 年 10 月 30 日

    受益匪浅啊

  4. Damon Zhao 2013 年 10 月 30 日

    Nice

发表评论