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层的内存泄漏问题,避免内存泄漏小问题日积月累造成较大影响;
  • 捕获并处理异常;
  • 采用多线程技术时小心使用锁。