看苏宁易购的运营保障体系如何 hold 住 818 大促

阅读数:401 2018 年 8 月 28 日

运营质量的好坏关系着用户的体验。在日常的业务运营过程中,商品无货、页面或券过期、商铺下架、视频无法播放等问题都严重影响用户体验。如果仅凭运营的人工监控和维护来保证服务质量,不仅效率低,而且效果也不佳。业务的需求是驱使技术革新的原动力。818 前夕,面向苏宁易购线上运营质量保障的先知平台正式上线。

先知平台的设计理念基于“As was foreseen”,正如预想的那样,线上运营过程的服务质量是完全可控制的。先知运营保障体系包括线上故障发现、应急响应、故障定位、快速恢复,形成完整闭环,能自动化帮助运营修复线上问题。

下面就来看一看先知平台背后的技术实现细节。

图 1. 基于先知的运营保障体系

基于 Selenium ChomeDriver 的性能监控

先知平台最基本的功能是模拟用户(带有真实用户会话信息)来对页面进行扫描(爬虫),在浏览和购物的过程中发现潜在的运营问题。我们将问题分为三类:业务、功能和性能。业务类问题包括商品无货、页面或券过期、商铺下架等;功能类问题包括数据埋点缺失、风控失效、推荐降级等用户无法直观感受,但会产生严重后果的问题;性能类问题包括页面 yslow 评分、状态码错误、接口响应超时等问题。

技术上,我们基于 Selenium ChomeDriver 实现对页面的扫描,它提供了一套用于 Web 应用程序的自动化爬虫工具。这里有几个技术实现细节值得分享:

  1. ChomeDriver 使用的是 Headless 模式。Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。相比于 UI 操作,Headless 模式大幅提高了我们的扫描效率和性能。
  2. 实现了针对页面性能数据的采集。一般的爬虫主要是针对功能逻辑的验证,很少覆盖页面和接口的加载性能。我们参考谷歌的 Chrome DevTools Protocol,开启 ChromeDriver 的 PERFORMANCE 日志,可以收集到页面交互过程中的页面(Page)性能和网络(Network)性能数据。
  3. 启用 ChromeDriverService。这完全是出于提高测试性能的考虑。我们知道每次创建一个 ChromeDriver,完成测试以后再释放掉这个对象,等下次来了一个新的测试,仍要再新建一个对象,如此反复。这相当于每次都打开浏览器,再关闭浏览器,再打开浏览器。这种实现方式并不利于高并发大规模的使用。我们希望如 Java 的池化设计思想一样,初始化生成多个持久化的浏览器对象,后面每次测试都用这些浏览器对象进行,这样会极大提升测试性能,避免了往复创建和关闭 Chrome 进程的过程。因此引入 ChromeDriverService,ChromeDriverService 是一个管理 ChromeDriver server 的的持久化实例。

下面是一个简单 demo:

复制代码
// 设置 Chromedriver 路径
System.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY,
                   System.getProperty("user.dir") + "/drivers/chromedriver");
// 启用 ChromeDrvierService 持有浏览器进程
ChromeDriverService chromeDriverService = new ChromeDriverService.Builder()
                   .withVerbose(true)
                   .usingAnyFreePort()
                   .build();
// 启用 Headless 模式
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
{1}
// 开启 PERFORMANCE 日志采集
DesiredCapabilities cap = DesiredCapabilities.chrome();
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
cap.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
cap.setCapability(ChromeOptions.CAPABILITY, options);
{1}
driver = new ChromeDriver(chromeDriverService, cap);

动态编译引擎 DynamicEngine 实时加载监控脚本

在监控的过程中,不同的业务需要关注的指标往往不同,且随着促销活动的进行不断变化。比如,之前我们没有对商品售罄状态的监控,运营有这样诉求时,要求我们必须马上能在生产环境实现对商品状态的监控。为了做到监控脚本的热拔插,我们自己实现了动态脚本编译引擎 DynamicEngine,能够实时在生产环境增加监控模板,面对需求变化具备灵活的可扩展性。

要实现 DynamicEngine,基于 JavaCompiler 读取源码,编译诊断,输出 class。JavaClassObject 负责文件抽象,代表源代码或者编译后的 class。ClassFileManager 管理 JavaClassObject,负责 JavaClassObject 的创建和保存位置,根据 Java ClassLoader 的双亲委托模式,我们需要实现自己的 DynamicClassLoader,DynamicClassLoader 继承自 URLClassLoader,将生成的 class 动态加载到 JVM。

图 2. DynamicEngine 类依赖图

Quartz 实现定时任务调度

定时任务的实现基于 Java Quartz,Quartz 是目前最为成熟, 使用最广泛的 Java 任务调度框架。Quartz 运行时由 QuartzSchedulerThread 类作为主体,循环执行调度流程。JobStore 作为中间层,按照 quartz 的并发策略执行数据库操作,完成主要的调度逻辑。JobRunShellFactory 负责实例化 JobDetail 对象,将其放入线程池运行。LockHandler 负责获取 LOCKS 表中的数据库锁。

图 3. Java Quartz 任务调度交互图

先知的监控模式包括主动监控、被动监控和漫游监控三种。主动监控是运营在后台直接配置的监控任务。被动监控是与业务系统打通,提供公共接入 API,运营页面或者事件生成时自动构建监控任务。漫游监控的设计初衷借鉴了 Chaos Monkey 的思想,运营很难知道下一个出问题的是哪一个活动页面,既然如此,我们建立了从流量入口页开始的漫游任务,会不断爬取链接建立任务来发现问题。不同的监控模式的集群是隔离的,避免任务占用资源互相影响。

图 4. 先知平台的任务调度

先知智能运营的场景应用

前面我们所阐述的监控扫描、脚本执行和定时任务调度方案,虽然能帮助运营发现线上问题,但解决问题仍需要运营的人工干预。在某些情况下,运营并不能及时完成页面的修复和维护,需要自动化的运营方案。所以,先知不仅仅是一个针对运营的监控告警平台,它还能自动化修复线上问题。

智能运营的设计思想是,先知与推荐系统、泰坦系统(运营内容管理平台)打通。如下图所示,我们以促销商品售罄问题为例,当先知发现这个问题后,先判断这个商品坑位是否允许降级,如果允许,则调用推荐系统,根据用户信息推荐出与此款商品偏好类似的替代商品。在通知泰坦系统,将替代商品维护到这个坑位。这样既保证了线上热点坑位始终有货可卖,又满足了用户的购物偏好,保证了用户体验。

图 5. 先知智能运营的场景应用

总结    

目前,先知承担了苏宁易购所有线上运营页面和活动的服务保障工作,日监控任务 10 万余个,发现并解决问题 6400 余个,帮助运营迅速定位线上问题,平均缩短解决问题时间 30 分钟,显著提高了易购的线上服务质量。未来,苏宁易购将致力于把先知打造成为开放的一站式线上服务质量保障平台,大规模监控任务并发执行、海量数据分析、智慧运营服务化都将成为苏宁易购新的技术研究和攻关课题。

作者简介

朱羿全,南京航空航天大学硕士研究生毕业,苏宁易购消费者研发中心高级技术经理,主要负责易购各系统架构优化与大促保障工作。先后参与了易购整站 Https 改造、苏宁拼购架构改造、先知业务监控平台建设等工作。专注于打造高可靠、高性能、高并发服务系统的技术研究。

收藏

评论

微博

发表评论

注册/登录 InfoQ 发表评论