2017 年 3 月 25 日,又拍云在广州举行了 Open Talk 唯品会专场“如何打造高性能高可用的电商平台”。


唯品会资深开发工程师赵勇带来了《新一代应用网络系统-智能路由》的精彩演讲,结合唯品会智能路由项目关键技术点,分享踩坑经验。


Clipboard Image.png

一、50% 的用户期望 App 加载时间在 2 秒内

速度尤为重要,数据表明,50% 的用户期望一个 App 的页面加载时间在 2 秒内。亚马逊的统计数据显示,如果每个页面延迟 1 秒加载,它将造成 16 亿美元的损失。谷歌认为加入智能路由后,能提高响应速度和网络联通率,增强系统可靠性。对于电商平台而言,速度意味着用户和订单。


移动设备网络环境复杂多变,鉴于域名服务器(DNS)解析耗时间,出现故障无法迅速回复以及容易受劫持等问题,唯品会团队希望通过移动设备本身进行网络探测,动态选择适宜路由,加快访问速度。

二、唯品会智能路由系统构成及关键技术

1. 唯品会智能路由系统组成情况

Clipboard Image.png


如上图所示:智能路由的核心原理是通过手机端集成路由 SDK,直接完成域名到 IP 的转换,提高访问速度。实现这一过程需要有相应的配置服务,灰色部分是智能路由系统重点部分,包括探测模块、评估模块和获取配置,中间核心的配置是一块路由表,所有东西都围绕着路由表转。


智能路由系统客户端流程包括 App 启动,获取配置,探测,评估,提供服务等。其中,探测会监测所有节点的返还时间,唯品会通过算法对它进行排序,并且跟监控系统、配置同步连在一起,一旦发现问题可以和配置服务采取相应措施。


快速和可靠是智能路由系统设计的难点即重点。快速意味着提供的服务确实能够快速地响应,可靠也就是提供转换的较差情况便是找不到合适的IP,但也能把原来的域名给返回出去,不影响域名的正常解析。

2高性能智能路由系统关键技术

为了提高性能唯品会进行了慎重的技术选型。 


Clipboard Image.png


  • C++跨平台开发


唯品会在移动端要跨平台同时支持安卓和 iOS,因此选择了性能非常友好的 C++,底层是 commmon C++ Library。


  • 多线程


尽可能地利用多线程技术并行探测,缩短探测时间,提升探测效率。


  • 改造探测 IP


Clipboard Image.png


上图所示,左边是逐个探测过程,右边改成批量探测,比如域名 1、2、3 对应的是同一个 IP 的节点,结合多线程与批量探测技术,唯品会能够做到对所有节点做完一次探测,给 App 提供好的智能服务。


  • 缓存路由表


Clipboard Image.png


将上次批量探测结果,以类似数据库的形式存下来,便于后续的查询、删除、修改和扩展。


  • 三层Map结构


Clipboard Image.png


基于系统考虑,如上图所示,左边是两个三层的 map,第一个 map 通过域名和网络快速查找 IP,它主要是方便 App 的使用,右边是提供一个 IP,快速找到一组域名,并进行快速地批量探测。有了这两个 map后,一个 App 如果第二次启动,便可立刻接受服务。


  • 无缝合并路由表


如果配置发生变化,需要重新拉取配置,两个 map 数据发生变化时该如何处理?


Clipboard Image.png


对此,唯品会的解决办法是这个时间不提供服务,等该 map 新生的配置全部弄好后,把 map 替换掉,为了在更新 map 的过程中也可以提供服务,唯品会采用无缝合并路由表并引入自研 C++ 开发读写锁。

三、智能路由系统踩过的坑及经验分享

1踩过的坑

  • Open SSL


智能路由系统采用 C++ 开发,但标准的 C++ 不支持网络保护,唯品会使用了有安全漏洞的 Open SSL 库被谷歌应用市场以不符合要求为由拒绝,升级 Open SSL 库得以解决。


  • 对埋点的影响


智能路由系统会在短时间内进行大量探测,如果对探测的结果都进行埋点,客户端埋点系统需要支持缓存和批量埋点上报,否则影响客户端应用性能。

因此如果需要大批量埋点上报,埋点系统本身要做的更健全和可靠,且埋点本身支持批量上报,减少带宽。


  • Android 跨域重定向失败


App 为了可以和 IP 直连,唯品会使用了标准的 Host Header 表示原来的 domain,但 Android 使用的 Apache HttpClient copy  了 original request 里的 Headers,导致跨域重定向失败。


解决方案有以下几种:


使用定制的Header;


改造网络库;


修改服务端代码,除去重定向;


暂时 disable 部分功能。

2经验分享-避免崩溃 

Clipboard Image.png


因为安卓机型复杂很难定位,智能路由项目的挑战是面对C++ 和 Crash 的问题。


对此给出几点经验:


明确 C++crash 如何定位;



需要考虑 JNI层的内存泄漏问题,避免内存泄漏小问题日积月累造成较大影响;


捕获并处理异常;


采用多线程技术时小心使用锁。