2017 年 3 月 25 日,又拍云在广州举行了 Open Talk 唯品会专场“如何打造高性能高可用的电商平台”。唯品会资深开发工程师赵勇带来了《新一代应用网络系统-智能路由》的精彩演讲,结合唯品会智能路由项目关键技术点,分享踩坑经验。
一、50% 的用户期望 App 加载时间在 2 秒内
速度尤为重要,数据表明,50% 的用户期望一个 App 的页面加载时间在 2 秒内。亚马逊的统计数据显示,如果每个页面延迟 1 秒加载,它将造成 16 亿美元的损失。谷歌认为加入智能路由后,能提高响应速度和网络联通率,增强系统可靠性。对于电商平台而言,速度意味着用户和订单。
移动设备网络环境复杂多变,鉴于域名服务器(DNS)解析耗时间,出现故障无法迅速回复以及容易受劫持等问题,唯品会团队希望通过移动设备本身进行网络探测,动态选择最佳路由,加快访问速度。
二、唯品会智能路由系统构成及关键技术
1. 唯品会智能路由系统组成情况
如上图所示:智能路由的核心原理是通过手机端集成路由 SDK,直接完成域名到 IP 的转换,提高访问速度。实现这一过程需要有相应的配置服务,灰色部分是智能路由系统重点部分,包括探测模块、评估模块和获取配置,中间核心的配置是一块路由表,所有东西都围绕着路由表转。
智能路由系统客户端流程包括 App 启动,获取配置,探测,评估,提供服务等。其中,探测会监测所有节点的返还时间,唯品会通过算法对它进行排序,并且跟监控系统、配置同步连在一起,一旦发现问题可以和配置服务采取相应措施。
快速和可靠是智能路由系统设计的难点即重点。快速意味着提供的服务确实能够快速地响应,可靠也就是提供转换的最差情况便是找不到合适的IP,但也能把原来的域名给返回出去,不影响域名的正常解析。
2. 高性能智能路由系统关键技术
为了提高性能唯品会进行了慎重的技术选型。
C++跨平台开发
唯品会在移动端要跨平台同时支持安卓和 iOS,因此选择了性能非常友好的 C++,底层是 commmon C++ Library。
多线程
尽可能地利用多线程技术并行探测,缩短探测时间,提升探测效率。
改造探测 IP
上图所示,左边是逐个探测过程,右边改成批量探测,比如域名 1、2、3 对应的是同一个 IP 的节点,结合多线程与批量探测技术,唯品会能够做到对所有节点做完一次探测,给 App 提供最好的智能服务。
缓存路由表
将上次批量探测结果,以类似数据库的形式存下来,便于后续的查询、删除、修改和扩展。
三层Map结构
基于系统考虑,如上图所示,左边是两个三层的 map,第一个 map 通过域名和网络快速查找 IP,它主要是方便 App 的使用,右边是提供一个 IP,快速找到一组域名,并进行快速地批量探测。有了这两个 map后,一个 App 如果第二次启动,便可立刻接受服务。
无缝合并路由表
如果配置发生变化,需要重新拉取配置,两个 map 数据发生变化时该如何处理?
对此,唯品会的解决办法是这个时间不提供服务,等该 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. 经验分享-避免崩溃
因为安卓机型复杂很难定位,智能路由项目最大的挑战是面对C++ 和 Crash 的问题。
对此给出几点经验:
- 明确 C++crash 如何定位;
- 需要考虑 JNI层的内存泄漏问题,避免内存泄漏小问题日积月累造成较大影响;
- 捕获并处理异常;
- 采用多线程技术时小心使用锁。