开发者社区> stevechen1010> 正文

移动端 IP 优选方案

简介: 无论是从 Local DNS 解析域名,获取到 IP 列表,还是从第三方的 DNS 解析服务中,获取到域名对应的 IP 列表。我们获得多个 IP 后,总是想选取一个最优的 IP 使用,本文主要探讨如何在客户端探测 IP 的连接性以及连接速度,保证返回可用性最好的IP,以达到“IP优选”的目的。
+关注继续查看

移动端 IP 优选方案

1. IP 优选目的

无论是从 Local DNS 解析域名,获取到 IP 列表,还是从第三方的 DNS 解析服务中,获取到域名对应的 IP 列表。我们获得多个 IP 后,总是想选取一个最优的 IP 使用,本文主要探讨如何在客户端探测 IP 的连接性以及连接速度,保证返回可用性最好的IP,以达到“IP优选”的目的。

2. 新浪开源的 httpdns 的 sdk 里的测速逻辑

新浪开源一个 HTTPDNSLib ,里面包含了测速逻辑,GitHub地址如下:

我们以该 sdk 里的测速逻辑为例进行原理解析。

3. IP 测试实现原理

使用 linux socket connect 和 select 函数实现的。 基于以下原理:

  1. 即使套接口是非阻塞的。如果连接的服务器在同一台主机上,那么在调用connect 建立连接时,连接通常会立即建立成功,我们必须处理这种情况。
  2. 源自Berkeley的实现(和Posix.1g)有两条与select 和非阻塞IO相关的规则:
    A. 当连接建立成功时,套接口描述符变成可写;

B. 当连接出错时,套接口描述符变成既可读又可写。

详细的测速实现如下,原理参考注释:

以 iOS 实现为例:

- (int)testSpeedOf:(NSString *)ip port:(int16_t)port {
   NSString *oldIp = ip;
   //request time out
   float rtt = 0.0;
   //sock:将要被设置或者获取选项的套接字。
   int s = 0;
   struct sockaddr_in saddr;
   saddr.sin_family = AF_INET;
   // MARK: - 设置端口,这里需要根据需要自定义,默认是80端口。
   saddr.sin_port = htons(port);
   saddr.sin_addr.s_addr = inet_addr([ip UTF8String]);
   //saddr.sin_addr.s_addr = inet_addr("1.1.1.123");
   if( (s=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
       NSLog(@"ERROR:%s:%d, create socket failed.",__FUNCTION__,__LINE__);
       return 0;
   }
   NSDate *startTime = [NSDate date];
   NSDate *endTime;
   //为了设置connect超时 把socket设置称为非阻塞
   int flags = fcntl(s, F_GETFL,0);
   fcntl(s,F_SETFL, flags | O_NONBLOCK);
   //对于阻塞式套接字,调用connect函数将激发TCP的三次握手过程,而且仅在连接建立成功或者出错时才返回;
   //对于非阻塞式套接字,如果调用connect函数会之间返回-1(表示出错),且错误为EINPROGRESS,表示连接建立,建立启动但是尚未完成;
   //如果返回0,则表示连接已经建立,这通常是在服务器和客户在同一台主机上时发生。
   int i = connect(s,(struct sockaddr*)&saddr, sizeof(saddr));
   if(i == 0) {
       //建立连接成功,返回rtt时间。 因为connect是非阻塞,所以这个时间就是一个函数执行的时间,毫秒级,没必要再测速了。
       close(s);
       return 1;
   }
   struct timeval tv;
   int valopt;
   socklen_t lon;
   tv.tv_sec = HTTPDNS_SOCKET_CONNECT_TIMEOUT;
   tv.tv_usec = 0;
   
   fd_set myset;
   FD_ZERO(&myset);
   FD_SET(s, &myset);
   
   // MARK: - 使用select函数,对套接字的IO操作设置超时。
   /**
    select函数
    select是一种IO多路复用机制,它允许进程指示内核等待多个事件的任何一个发生,并且在有一个或者多个事件发生或者经历一段指定的时间后才唤醒它。
    connect本身并不具有设置超时功能,如果想对套接字的IO操作设置超时,可使用select函数。
    **/
   int maxfdp = s+1;
   int j = select(maxfdp, NULL, &myset, NULL, &tv);
   
   if (j == 0) {
       NSLog(@"INFO:%s:%d, test rtt of (%@) timeout.",__FUNCTION__,__LINE__, oldIp);
       rtt = HTTPDNS_SOCKET_CONNECT_TIMEOUT_RTT;
       close(s);
       return rtt;
   }
   
   if (j < 0) {
       NSLog(@"ERROR:%s:%d, select function error.",__FUNCTION__,__LINE__);
       rtt = 0;
       close(s);
       return rtt;
   }
   
   /**
    对于select和非阻塞connect,注意两点:
    [1] 当连接成功建立时,描述符变成可写; [2] 当连接建立遇到错误时,描述符变为即可读,也可写,遇到这种情况,可调用getsockopt函数。
    **/
   lon = sizeof(int);
   //valopt 表示错误信息。
   // MARK: - 测试核心逻辑,连接后,获取错误信息,如果没有错误信息就是访问成功
   /*!
    * //getsockopt函数可获取影响套接字的选项,比如SOCKET的出错信息
    * (get socket option)
    */
   getsockopt(s, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon);
   //如果有错误信息:
   if (valopt) {
       NSLog(@"ERROR:%s:%d, select function error.",__FUNCTION__,__LINE__);
       rtt = 0;
   } else {
       endTime = [NSDate date];
       rtt = [endTime timeIntervalSinceDate:startTime] * 1000;
   }
   close(s);
   return rtt;
}

目前 《阿里云 HTTPDNS SDK 》 内部已经集成了该逻辑,如果有兴趣可以进钉钉群交流:"【客服群】阿里云移动服务-HTTPDNS",群号:11777313。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
CDN工作原理及其在淘宝图片业务中的应用
淘宝的图片访问,有98%的流量都走了CDN缓存,只有2%会回源到源站,节省了大量的服务器资源。 但是,如果在用户访问高峰期,图片内容大批量发生变化,大量用户的访问就会穿透cdn,对源站造成巨大的压力。 今年双11,淘宝鹿班的主图价格表达升级项目,就面临了这种挑战,让我们看看是如何解决的吧。
1289 0
淘宝全站HTTPS 百万页面改造技术细节大起底
电商启用全站HTTPS是一件门槛极高的事情,它需要投入巨大的资源,不仅是人力、财力等方面,而且对技术能力也提出了极为苛刻的要求。
24044 0
微信公众平台推广功能公测了 广告主流量主赶紧去占地吧
  微信公众平台推广功能今天开始公测了,关注用户数10万以上的公众帐号可成为流量主(貌似门槛有一些噢),提供广告展示获取收入;公众平台关注用户达到5万即可开通流量主功能!不差钱的boss如果想寻求新的推广渠道可以考虑成为广告主噢,毕竟新平台大伙还不是很了解,反而竞争更小,广告单价更低,效果更好也会,不妨尝试着去当第一个吃螃蟹的人吧。
1102 0
网站防刷方案
目录[-] 网站防刷方案 网站重复请求解决方案 Mr. Neo Chen (netkiller), 陈景峰(BG7NYT) 1. 访问网站所涉及环节 2. 浏览器款控制方案 3. CDN 与 反向代理 4. 网络设备控制方法 5. 服务器上做控制 5.1. 操作系统部分 提示 5.2. WEB 服务器部分 6. 通过程序控制访问行为 提示 7. 总结 网站防刷方案 摘要 这是讲述如何防止重复请求你的网站, 包括如,爬虫,数据采集,刷排名,批量注册,批量发帖,利用漏洞获取网站数据等等。
2146 0
含ppt下载|解析支付宝移动端弹性动态架构
支付宝在移动端如何实现轻耦合、弹性动态的开发模式
369 0
五种搭建直播网站的方式,你更喜欢哪一种?
各式各样的直播网站搭建起来,随着时代的发展不断增长,没有人能预测,下一刻,谁会爆发成为新的黑马,而你,又更喜欢哪种类型的搭建方式呢?
1195 0
浅谈阿里云PCDN原理及接入 几行代码能节省上百万的黑科技到底是什么?
距离PCDN上线时隔五个月,不少用户已经成功接入并且上线运行了一段时间。其中绝大部分客户反馈加速效果得到优化,视频首播时间、流畅率等核心性能指标均有提升。与此同时,每月的CDN费用得到了有效缩减,平均降幅超过40%,真正做到了质量提升而成本降低这一原则。
4008 0
怎么搭建短视频系统?全套负载均衡方案
负载均衡的表述性解释咱不再说明,自行谷歌或百度即可。这里主要介绍两种负载均衡的方案。
1511 0
+关注
stevechen1010
移动开发工程师,现在在研究混合开发技术。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
聚划算iOS平台动态化方案LuaView
立即下载
负载均衡是如何支撑几亿手机微博用户访问的 -高性能负载均衡研发和应用实践
立即下载
LuaView-聚划算动态化方案
立即下载