赵云霄,京东商城无线业务部首席架构师。2011年加入京东进入无线团队,负责服务端的开发与架构设计工作。见证并参与了京东无线从小到大,由弱到强的整个过程。五年间,带领团队完成了无线服务端的两次重大架构升级,无线服务端从一个简单的Web应用进化成为支撑每天几十亿级访问的分布式系统。目前负责京东无线网关系统的研发工作。
陈保安,京东商城无线业务部研发高级经理。从事研发工作十年,2011年加入京东。目前主要负责无线核心业务(搜索、商品、购物车、结算、收银台)的后端研发工作,多次带领团队进行系统架构升级和多次大促经历磨练,为京东无线核心系统后端服务稳定性打下坚实基础,支撑无线千万级的活跃用户和JD过半的订单占比。
InfoQ:为了备战今年的618大促,京东做了很多演习。请具体介绍一下移动端演习的内容、分类和流程,以及演习时的模拟数据是怎样设定的。
做演习的目的,一方面是测试系统所能承受流量的能力;另一方面是,测试在某些环节出现问题时,我们切换预案的执行效率如何。这两方面同时也是我们在做演习时的主要内容,所以演习相应地分为压力测试和预案切换两类。
演习的数据有两种,一种是线上流量,一种是造数。
陈保安:我重点从下单之前和下单之后这两个环节说一下模拟数据。
InfoQ:在618的期间的数据跟平时可能会有些不同,例如某些热销产品,数据变化较大,针对这种情况是不是会做一些特殊的处理?
赵云霄:因为过热的商品会造成访问数据集中在某一片缓存上,这有可能会暴露出系统设计上的问题。我们会通过技术的手段解决这种问题,然后将测试数据集中在上面,来看测试效果。
InfoQ:那方便说一下具体采用了哪些技术手段吗?
赵云霄:总得来说就是,设置多级缓存,同时尽量让第三方缓存的请求变得更散。
InfoQ:网络的复杂情况给移动端带来了很多问题。为了保障用户的最佳体验,京东做了很多适配工作,并在接口层面做了做了相应的设计。请您具体讲解一下适配的标准,以及接口的设计根据618大促的需求做了哪些改变。
陈保安:因为网络的复杂情况而带来的这些问题主要是由于手机端与PC有着不一样的特性。
首先,从网络流量和耗电量来看,图片加载对手机的消耗比较大。而从进到首页到后端搜索,再到商品详情,我们展现给用户更多的就是图片。所以,我们对图片会重点处理:根据不同的分辨率、不同的网络类型、不同的手机系统版本(安卓4.X版本和之前的版本区别较大),指定了相应的标准。这里是有一个比较大的escape标准东西,就是说有一个成熟的表单,它是由产品人员做了很多次测试得出的,在什么样的位置上,图片适配采用什么样的大小尺寸都有标准。
这一次618我们做的比较大的改动,就是规则的识别下发给了客户端。比如,刚刚提到的图片的识别规则原来是在后端去处理的,要根据手机的分辨率、网络类型、机器的版本去做适配,这样一来就涉及到静态化的数据,使得利用率变得非常非常低了。所以这一次我把这规则下放给了客户端,客户端只需要告诉后端是安卓的哪个版本,后台会给它下发统一标准的数据。而规则是动态下发给客户端的,比如说打开客户端以后,后端就把规则下发给了客户端。这样一来,后端就不需要再去根据分辨率、网络类型等去做适配,而是由客户端去做适配工作。
具体的下发的规则是统一的,包括在2G、3G等网络情况下分别对图片有怎样的要求。这一点是根据分辨率来固定相应的范围的,不是所有的范围,否则规则会太多。
赵云霄:总得来说是三点:
InfoQ:京东曾提到,在系统升级的过程中,会尽量减少强依赖,将强依赖尽量转化成弱依赖,并不是直接依赖于服务。能否举例说明减少了哪些强依赖,是如何将强依赖尽量转化成弱依赖的。
陈保安:强依赖转变成这弱依赖,或者说尽量不依赖,就是说我们对这于实时性要求不高的,像商品的信息,包括图片、特殊属性、详情、商家等信息,以前可能是完全依赖于基础服务的,现在会把它的一些数据异构并存储下来。在发生变化时,通过管道MQ去通知做出一些变更,达到最终不会实质依赖基础服务去做商品聚合展示的目的。所以现在,其实是间接依赖。因为这虽然不是实时,但是是通过异步的方式给我的。而像价格、库存等变化非常频繁的数据,依旧是实时依赖。
赵云霄:其实像京东的系统,是一个完备的包括所有业务的系统,是一个完全的服务化的系统。哪些是必须看成强依赖,哪些必须看出弱依赖,在我看来这个东西没法去区分。
京东有几百上千个服务,我们要去梳理这些东西,比如说哪些东西没有必要直接同步的去调用它,让它影响我们,我们会去把这些东西梳理出来。现在的套路,要不是异步化,要不就像保安说的有一些地方我可以用空间去换取更好的交互,所以要么是采用中间件,要么是异构一份数据到缓存中。
那么所谓减少依赖都是在正常服务不可用的极端情况下可以去考虑的,在正常的服务化系统之间的交互,我们还是尽量保证专门的系统去做其专门的事。例如,在平时,我们会去依赖A、依赖B、依赖C,而且还会调度它们,但是我们还会有一个异步方案,在特殊情况下,比如说在流量非常大的时候,去切换到这个方案上,这个方案对后端压力比较小。
所以我认为没有必要刻意总结哪些强依赖、哪些是弱依赖。在一个比较庞大复杂的服务系统中,你没有太多办法要求别人的系统去做一个什么什么事,而我们的系统也要配合别人的系统去工作,所以这个复杂就会更高。所以我们只能想办法,各自做一些在极端情况下能保护后端的方式,这就是我们减少依赖的目的,也是遵循了前端保护后端的通用原则。
InfoQ:那么也就是说在618期间流量比较大时,可能会做出一些取舍,比如用空间去换取交互效果。那么在大促结束之后,会不会换一套方案把之前做的牺牲再换回来?
赵云霄:这是有可能的。因为在严谨的系统设计中都会有备选,在特殊情况下必须用空间去换取想要的效果,但是日常的流量情况不需要牺牲额外的空间。既要节省成本,又要保证正常的交互。另外,就像刚才提到的很多弱依赖的场景其实是个别情况,在大部分交易流程中,很多依赖还是实时的。把需要实时反馈的数据转换成弱依赖,实际上是我们做出的妥协。所有的这种妥协,在回归正常情况时,我们都有可能收回。
陈保安:做出妥协是非常必要的,领导曾说,我们虽然要依赖一些基础服务,但是基础服务真的挂了的时候,自己还要保证能活,这就是我们的最终目标,就是说要在基础服务出现问题的时候,我们能够有办法快速地去解决问题,而不是处于死等状态。
赵云霄:任何一个大型在线系统,它的主干要是最强壮的。我们可以减少分支上无关紧要的东西,来保护最重要的部分免受大流量的破坏,让它处于安全的保护之内,能提供正常服务。同时,由于用户体验非常重要,又涉及到京东很多用户,所有我们会多考虑出20%,比如考虑流量达到120%的时候要做出什么方案来保护它。
InfoQ:这些预案都是来处理特殊情况的,而在实际的大促过程中,为了保证万无一失,京东还做了很多监控工具和监控平台,那么京东都是从哪些纬度来进行监控的?移动端的监控平台有哪些?具体采用了什么技术?
赵云霄:事实上,在刚起步时,我们也缺少监控,经常半夜被叫醒处理技术问题。后来我们逐渐意识到,监控系统跟核心系统是同等重要,应当把监控系统看做正常业务系统的一部分。比如说,要新上一个业务系统,那么监控系统就占50%,没有监控系统就不可以上线。
从无线端来看,监控系统是多维度的。从底层的操作系统的各项指标,到各个层面的业务系统,再到网络都需要监控。
这些监控都是非常必要的,比如业务监控,有时候业务表面上是存活的,但是业务不正常,有可能出现很多逻辑上的问题,所以移动端还有对订单量、购物车、搜索等方面的监控,这些监控是业务指标级别的,也是应用层面的。我们有对应用主动调用的检测,不同的VIP进来,这就是从应用层面的存活激活,还有一些其他。各个团队如果感觉这应用不够,还会自己添加一些小的应用系统跑在机器上去监控。
另外还有对运维、云平台和网络层面的监控,这些监控一起形成了一个比较立体的监控系统,从底层到最上层都有监控。
目前,移动端涉及到的监控平台有以下几个:
InfoQ:刚才提到,京东的监控做得非常立体,有很多团队去做。那么有没有统一的管理,或者说一些原则?有没有专门的人去对监控系统做审查?
赵云霄:监控点的加入是渗透在系统的设计中的。例如,系统的初期就应该对业务指标的数据进行监控,这是一个上线之前的规则。我们会定期做考察,如果有些该设置埋点的地方没有设,那么QA人员会做处理。
埋点的原则主要有以下四点:
赵云霄:是的,而且我们的运维有研发能力,这是对互联网研发人员一个最基本的要求。
陈保安:各个团队做的职责不一样。比如说各个机房的流量分配运维更偏向于网络层、包括服务器层这些基础组件的监控。网关层面更注重的是流量的监控,所以业务团队除了一些基本业务指标监控之外,也会做一些业务细节的监控,比如可用率、性能、异常量、错误码等等。比如说某个点的单量突然跌了,需要尽快定位到具体是什么原因引起,所以业务侧的监控更多是能一眼就能聚焦到引起问题的某个点上,通过预案快速修复问题。
而且我们上线、发布新的业务,都是要有灰度的。比如上线一个业务之后,只是其中的一部分流量走新业务。此时,我们通过埋点监控,去对比新老业务,看用户的反应,分析其影响,然后再做决策。
InfoQ:刚才提到埋点,那么大促过程中移动端设置的埋点跟平时有没有不同?大促结束后会不会关闭某些埋点?
赵云霄:埋点的作用分两种,一种是用来收集业务数据的埋点,另一种是监测系统指标的埋点。大促之前,我们会针对不同促销会增加一些的收集业务数据的埋点。京东的业务非常复杂,跟单纯做平台其实是不一样的。市场有时会做一些新业务,这时就可能要根据业务再判断如何增加埋点。用来监测系统指标的这些埋点基本不会变。
埋点基本上都是可以去关闭的。埋点要么是通过现在的技术,通过APP内网去申报,要么就是写在磁盘日志上。这两种埋点对网卡和磁盘都会造成比较大的损耗,所以没有用的埋点,我们会想办法动态关闭。
InfoQ:京东做了一套立体的监控,又设置了很多埋点,那么肯定是可以监控到非正常用户的。具体是怎样筛选出非正常用户的?移动端在管控这些非正常用户方面做了哪些工作?怎样保证快速隔离非正常的用户?
同时,在安全方面客户端和服务端之间也有一些基本的接口调动时候的安全限制。比如说签名,我会给你分配到签名,你要拿到对应的签名才能去访问相应的服务,这里也会有几种策略下发给客户端去用。但是非正常用户为什么可以刷单,就是因为破解了个别签名。这也是为什么还需要后端不断地去对用户行为分析。
具体的隔离方式:针对非正常用户,在关键时刻我们会做非常严格的限制,否则会对系统和商品销量造成很大的冲击。例如,在618和双十一零点时,会对识别出的用户做特殊处理。表面上会给他们提供一些服务,但实际上会把他们引流到一个具体的集群中,性能、稳定化不做保障,如果他们挂掉了,我们也不负责,这样才可以对正常用户做到保护。而即使是引流,他们最终访问的流量还是会透传到各个基础服务,在特殊紧急情况下,也会把这些用户掐掉。这些不同级别的限流都已经经过了演习并报备,目的都是为了保证正常用户。
InfoQ:相当于把非正常用户加入了黑名单,那么这份黑名单是怎么得到的呢?
赵云霄:得到这份黑名单非常不容易。京东有非常多的数据,也希望能利用这些数据对用户提供更好的服务。京东有一个专门的团队,利用大数据分析,通过数据模型不断地调整、优化,再利用从前端到后端的多级防控,才从海量的数据中分析得出用户的画像。
无线团队也会做一些比较简单的用户分析,也会要求他们为我们提出安全点。大家始终在做这种配合,然后根据用户的不同级别,做一些反馈。比如,像刚才提到的,在特殊情况下掐掉的非正常用户,都是我们真正有把握的非常用户,而不是模棱两可的。正常用户去抢购商品是不会被加入黑名单的,这样才能真正包含用户的利益。
同时,我们队黑名单也会做出动态调整。因为不同业务的业务模型是不一样的,对用户的分类是有差别的。所以需要跟专门的团队去沟通,让他们根据业务模型分析非正常用户。实际上,非正常用户的占比也是非常小的,这也让我们非常欣慰。
陈保安:这模型建立固定好后,通过埋点实时地埋过去,就可以算出真正的非正常用户。在大促时,经常遇到有人临时去注册一批用户的情况,但是只要他开始刷单,我们很快就能够识别出来。
InfoQ:据我所知,无线端对整个购物流程都做了非常细致的预案,能不能具体地说一下细致到了什么程度?开启的方式是自动化吗?在什么样的情况下会启动预案?
陈保安:整个京东针对618做了上千种预案,而无线部门也做了几百种预案,这个力度是都非常非常细的。大的预案例如机房的切换,而小的预案也有很多。
比如,京东App上搜索现在70%搜索的结果都是个性化的,这样一来缓存命中率会降低,服务器的压力就会增大。如果CPU使用率达到了40%,那么我们会通过降级个性化服务来保证用户能够快速访问。再比如现在支付环节要依赖京东台账和订单中心,如果服务出问题,我要通过降级保障用户能正常支付。
关于何时启动预案,虽然往年我们为了保证最基本的购物体验,我们在零点时会做一些处理降级。但今年晨总要求了两点,一是技术保障,最基本的要求,二是业务驱动指标,就是说不能随便降级,要保障业务。
所以,包括之前提到的个性化,以往在零点去做一些降级,但是今年不会去做降级。但是一切大前提就是保障基础购物流程的体验,关键时候系统自我的保护就会启用一些预案,比如说单品页下面的个性推荐,只要它达到基础性能的某个比例后,我们就会采取一些紧急措施来保证整体商品的展示。
赵云霄:事实上每年都会做很多预案,在大促前都会有一个严格的评审。细致到什么程度呢?比如后端依赖某一个具体的接口,针对每一个接口都要有一个预案,包括资源的依赖都会有原。我们是尽可能地去考虑可能出现的问题。
预案启动的方式是自动还是人工需要看情况。
有了之前提到的强大监控系统来提供一些判断依据,预案的执行效果还是比较好的。
事实上,预案有专门的分归类,不同模块的人会去管理自己的预案。在执行时也会遵循保证用户正常体验的大原则。
InfoQ:京东的无线端一步步发展至今,两位想必有很多感慨吧?
陈保安:对,我跟云霄就是从无线成立到现在,一步一步走过来的。在四五年前,无线只是试水,那时我们还叫手机移动端。上了一万单时,大家很开心,还专门庆祝了一番。现在,我们的访问人次和订单量在当时都是难以想象的,比如,过去一个月的日均活跃用户数已经接近4000万,技术团队由最初的两三个人发展到现在的过百人,有了比较完善的架构。
京东给了移动端快速成长的机会,让我们不断进步。我们也一直保持着对技术的旺盛求知。网上有一些技术贴,说京东的技术如何如何,我们没人去霹谣,因为谣言太多了。你可以说京东只是流量很大,但我会说京东的系统复杂度是最大的。我们经历了这么一个体系的成长,现在也有了一个足可以让我们自己去仰望的平台。