移动端 IP 优选方案

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 无论是从 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。

相关文章
|
存储 负载均衡 网络架构
百度搜索:蓝易云【动态bgp和静态bgp相比有哪些优势?】
需要注意的是,选择动态BGP还是静态BGP应根据具体的网络需求和环境来决定。大型复杂网络通常会选择动态BGP以获得更好的灵活性和自动化能力,而小型简单网络可能更适合使用静态BGP以简化管理和配置。
142 5
|
5月前
|
域名解析 网络协议 CDN
网站接入CDN全流程,共4步!
阿小云网站已通过ICP备案,但因广州节点导致全国访问速度不佳,计划接入CDN以提升速度。以下是接入阿里云CDN的四步流程:1) 开通CDN服务;2) 添加加速域名;3) 验证域名归属权;4) 配置CNAME解析。详细指南见阿里云CDN页面:
507 0
|
6月前
|
缓存 前端开发 API
云:CDN配置思路-1
云:CDN配置思路-1
171 2
|
6月前
|
存储 弹性计算 关系型数据库
100W用户、8000W流量在线贺卡应用架构如何优化?
100W用户、8000W流量在线贺卡应用架构如何优化?
|
CDN
阿里云5大基础产品——CDN内容分发网络
阿里云5大基础产品——CDN内容分发网络自制脑图
158 0
阿里云5大基础产品——CDN内容分发网络
|
域名解析 网络协议 CDN
|
调度 CDN
《飞天技术汇—百T级CDN智能流量调度系统的实战分享 曾福华》电子版地址
飞天技术汇—百T级CDN智能流量调度系统的实战分享 曾福华
258 0
《飞天技术汇—百T级CDN智能流量调度系统的实战分享 曾福华》电子版地址
|
负载均衡
《负载均衡是如何支撑几亿手机微博用户访问的 -高性能负载均衡研发和应用实践》电子版地址
负载均衡是如何支撑几亿手机微博用户访问的 -高性能负载均衡研发和应用实践
84 0
《负载均衡是如何支撑几亿手机微博用户访问的 -高性能负载均衡研发和应用实践》电子版地址
|
存储 域名解析 缓存
CDN工作原理及其在淘宝图片业务中的应用
淘宝的图片访问,有98%的流量都走了CDN缓存,只有2%会回源到源站,节省了大量的服务器资源。 但是,如果在用户访问高峰期,图片内容大批量发生变化,大量用户的访问就会穿透cdn,对源站造成巨大的压力。 今年双11,淘宝鹿班的主图价格表达升级项目,就面临了这种挑战,让我们看看是如何解决的吧。
1901 0
CDN工作原理及其在淘宝图片业务中的应用
|
存储 缓存 编解码
产品更新 | 阿里云CDN边缘图像处理功能开放内测
在当下的网络环境中,企业在进行图片内容分发时,需要更快捷、高效地进行图片转换,以此适配各终端屏幕的分辨率、图片格式以及用户所处的网络环境,来提升展示效果。与此同时,海量的高质量图片往往会消耗较多的带宽,企业也需要在成本和质量中间找到最佳平衡点。为了更好地服务企业客户,阿里云CDN「边缘图片处理」功能结合不同的客户端、网络环境、图片规格,在边缘节点为客户交付最优的图像管理能力。
1607 0
产品更新 | 阿里云CDN边缘图像处理功能开放内测