2019年10月26日,由Testin云测主办的第二届NCTS中国云测试行业峰会在京召开,此次峰会以“AI+未来”为主题,汇聚来自国内外测试领域的知名专家学者、领先企业决策者、高层技术管理者、媒体从业者等,共同探讨高端云测试技术,帮助测试从业者了解最前沿行业趋势,及最新的行业实践。
会上,京东零售技术与数据中台测试架构师侯磊做《从链路化压测到流量回放的平台实践》主题演讲。侯磊介绍了京东在链路化压测方面的实践以及今年在工具上的演进,并指出,“开源社区星级最高的往往不是技术最牛、最好、最新颖的,而是论坛最丰富、社区最活跃,文档最全面的。当整个团队的能力逐步提升后,测试工具要想脱颖而出拼的就是运营了。”
以下为侯磊演讲实录:
谢谢大家,谢谢Testin云测给我这样一个机会和大家分享。和前两位讲师相比我的主题更细节一些、更专业一点。今天演讲的主题是《从链路化压测到流量回放的平台实践》。链路化压测去年、前年讲过很多次了,去年TID上也做过这样一个平台的分享,今天在Testin云测主场不以分享工具为主了,还是说压测方面的东西,以及今年在工具演进上做了哪些尝试,也是强业务相关的。开始之前,我先问一下大家真正做业务测试的有多少?做工具开发类的呢?如果都没有举手的就是领导了,大家注意一下周围的领导,可能他们需要挖人了。
我本人做开发出身,对工具平台会更游刃有余一点,今天还是把PPT做了一些调整。从性能测试开始主要分三个方面,先介绍一下链路化测试,再介绍一下我们平台是如何应对链路化测试的,最后是今年一个新的尝试点,流量回放。
说到流量,录制的方式其实有很多,我们从很多地方都可以录制流量,大家也都做很多尝试,比如java中的AOP拦截、机器运维手段(tcpcopy)、或者从LB层也可以。而今天我所讲的这个流量回放还是从全链路角度,从公司入口交换机上录流量,这样的录制的和基于应用服务器的录制还是有些区别的。
首先看链路压测,在京东性能测试有几个发展阶段,最初是线下测试,在这个阶段由各个功能团队执行性能测试,大家用的工具也比较分散,主要用于线下问题的定位、新部署系统的性能的评估,再往后,发现线下的测试不能满足线上的需求,线下的场景也不能复现线上的问题,同时mock的过程比较繁琐复杂。之后转为线上测试,再由线上的单点测试向集群测试过渡。在线上测试的时候,大家都会面临同样的问题——写流量,写流量就要做系统改造,这也是一个非常复杂,非常艰难的一步,上次分享的时候,大家都在问这样的问题,系统改造应该从何入手?我们改造的困难在哪儿?这个我在后面也会再提到。再之后,就是一些场景化,我们除了压单接口、压单服务,逐渐向组合业务、组合接口,包括刚才陆老师说到的BDD,这样一个在压测场景的应用。
现在开始做链路化压测,链路化压测又分为系统的链路和业务链路,这两个怎么理解?比如,压一个服务,这个服务会调我的缓存、调数据库、调其它中间件,这样就形成一个基于系统的流量的传输,这是天然形成的一个系统链路。业务链路呢?压一个接口,这个接口可能会调其他的接口,接口A调接口B,也可能调接口C,B有可能又调接口C,这样形成一个业务的链路。
在这个基础之上,如果我同时对ABC三个服务进行压测,或者说从多个入口进行压测,就会形成一个全链路的网状的流量结构。大家可以看这样一个图,如果压一个APP,它会调它的服务层,这样从一个入口进行压测的话会访问多中间层,最后到持久化。如果从多个入口同时压测的话,比如压APP1和web3,service2就可能会成为一个瓶颈。单压任何一个接口TPS都会很高,在组合情况下,service2可能成为多场景的短板,所以链路化压测就是要找到整个系统里面在全流量进行高峰访问时,到底哪些系统是短板,哪些应用的资源过剩了,做资源调整。比较典型的是京东开了海外站,海外和国内是有区别的,国内APP是主要的入口,泰国、印尼没有发展到这个阶段,PC就是主要的入口,这样的流量特点就会造成我们系统的资源分布是不同的,我们在海外站上线之前要对海外站做全链路压测,找到系统里面到底哪些资源需要做调整。因为在项目中,每个业务条线、每个开发都尽可能要更多的资源保证自己的系统不挂,而作为项目管理者,需要统筹规划,做好资源调整使资源达到平衡状态,最大化的发挥价值,节约成本。
所以说链路化压测主要是以下几个意义,首先是做整体流量的评估,我们的系统预期今年的双十一、618能够扛住多少量?我系统的短板是什么?其次是根据我的短板怎么再做资源的调配,让我们的木桶尽可能盛装更多的水,这是链路化压测的目的。
基于这样的目的,我们的工具平台又需要做哪些改进呢?首先看我们的链路化压测的核心需求,海量用户的模拟,链路化压测区分于以往的单机压测和集群压测,我们的目标群体是我们的主站上的所有应用,所以我们也需要有等量的压力机或者等量的用户发起流量访问,海量用户的模拟是必不可少的。第二点就是链路化发压的时候,压测团队是多个团队一起进行发压,如果有一条业务线压测的系统扛不住了,就需要降级或者需要减流量,另一种可能是有一条业务线的压测没有达标需要增加的流量,则需要把所有的任务都停止从头再来,这样的效率是不可接受的,所以要动态的调整某一个接口、某一些流量的访问量。第三点就是要模拟秒杀以及复合场景。随着京东组织架构的调整也经历过工具的变革,最初是有很多工具,各个业务功能团队执行性能测试,所以各自选型、各自为战,用的很多工具都有。第二阶段,随着京东业务量的提升,大促618、双十一的备战,组建专职的性能测试团队,这个在业界是比较少的,有专门性能测试团队,就有专门的经验积累以及工具的沉淀,大家选型三款工具,它们各有特点,jmeter上手比较方便。ngrinder是一家韩国的开源工具,这款工具第一次把压力机资源池、脚本资源池管理起来,这样的性能工具在项目管理上,知识沉淀上,是有优势的。gatling发压效率比较高。但是,这三款工具都不能满足链路化压测的要求,我们做了一个自己的压测平台,也是参考了很多压测工具的实现方式,这一点还得再说一下,在上次的分享之后,很多朋友都会问,京东的这个平台什么时候对外开放?开始很高兴加了很多微信,聊着聊着发现大家不是真的想做我们的用户,而是担心京东什么时候会成为竞争对手?这个我们目前是没有这样的计划的,我们还是一个对内的工具,我们也是希望借这样的机会跟大家交流工具的实践,因为我本身是做工具开发的。这个大家可以放心,Testin云测这边也没有任何竞争的关系。作为一个商业工具来说,它的门槛还是很高的,对内的测试工具即使功能再完善,可能对于用户的易用性还不是那么好,只是功能性多一点。
测试工具想在公司内推广,对公司每个组件、每个功能点都要支持,要支持数据库、支持消息中间件,测试人员也会提一些需求,甚至要一些智能化的东西,比如,自动寻找备测系统最大的处理TPS,这个是逐渐增加并发实现的,有一些自动停止的条件,比如,错误率是多少停止发压了,响应时间多少就停止发压。还有一种资源的调配,对压力机的资源、项目管理、对于测试计划、测试预警。还有作为一个压测平台也需要有一个整个性能测试的生态,包括监控,日志、性能调优的诊断工具,所有这些工具要在平台里做一个汇总。
因为我是做工具的,如果大家也是做工具的,可能也会遇到这样的问题,每个业务部门都会做自己的工具,接口测试工具、测试脚本管理、测试用例管理,每个部门都有自己的工具,做完这个工具又会面临一个推广的问题,跟同公司或者跟同业竞争的问题。性能测试工具相对于功能来说可能还好一点,因为这个门槛稍微会高一些。比如大家都会做性能测试,也都了解线程和进程,但是让大家真能说出来在性能测试里面什么时候用多线程并发、什么时候多进程并发,不是那么好回答的问题,所以做性能测试工具的时候,也是有一些难度的同样的需求,各个部门都会做工具,你的工具有什么突出点?首先一点还是技术的保障、技术的壁垒,这就是forcebot在京东内部的不可替代性。首先是海量用户的操作,下面我会介绍实现过程。另外一个是动态增减并发用户数,可以看到如图,这是模拟双十一的效果,在双十一0点的时候响应的请求突然有一个递增的效果,这就是秒杀活动,这个秒杀会持续一段时间,然后逐渐的减少,过一段时间可能有一个新的二次秒杀活动,这个流量又会上去,再逐渐的往下降,这是一个场景的模拟。为什么有这种场景?因为我们的系统现在做的很智能,我们要动态的缩容、增容,我们在秒杀之后的二次活动,二次洪峰来临的时候系统能不能扛住新的流量,这也是性能测试里面需要模拟的场景,做这个平台就需要支持这样的功能。
如图这是一个平台实现的基础架构,就不详细说了,其中有一点是任务调度服务,通过它的水平扩展支持海量的压力机进行并发的发压。
还是说一点我自身做工具的感想,做工具如果在内部推广最好有一个护城河。首先就是技术的门槛。如果让一般的测试工程师来做一些工具的开发,封一个页面,或者通过运维脚本驱动单机测试工具达到集成的效果,或者用一些开源工具包一层,这是大家最擅长、最容易做的。如果再提高一步做一些改良,例如多线程并发、流式计算,可能对于测试工程师来说这个门槛就稍微高了一点点,这是我作为工具开发的一点儿体会/心得。第二个护城河是当整个测试能力逐步提升后,拼的就是运营和维护了,开源社区星级最高的往往不是技术最牛、最好、最新颖的,而是论坛最丰富、社区最活跃,文档最全面的。在提升后,测试工具要想脱颖而出拼的就是运营了。
再回到系统里来,这里面有几个难点,1、海量数据的模拟,多并发就是通过海量的压力机、多线程、多进程实现。在双十一要想模拟百万级用户,至少需要四五千台压力机,每台压力机线程、进程也看容器的规格,好一点的机器支持并发多一点,差一点的机器一百并发就到头了。2、数据的收集,这是性能测试工具都会面临的问题,在jmeter为了精确计算TB99,会把每个响应时间都生成在文件里面,传给它的master,这样就造成了网络传输的问题和计算问题。ngrinder有了进一步的改造,它按秒收集单台压力机每个请求的响应时间,做一个汇总,求平均后再交给controller,由controller再进行二次平均,进行计算,当然这个数就有些失真了,所以我们在这里做了一点改进。首先还是数据合并,在压力机上把每个请求的响应时间都做了汇总,这个汇总不是求平均,而是做了数据压缩,把每一个响应时间的次数统计一下,把这个key-value的数据传到我们监控的平台上,这样传输的数据量变小了,同时在计算的时候,只要对map的key值进行计算就可以了,这是中间的小技巧。
还有作为一个压测的生态来说,监控是必不可少的,除了对压力机的监控还有被测服务的监控,监控的内容包括资源的监控还有发下请求的监控,对于性能监控来说一定是秒级的,往往程序里面GC时间很短,在频繁GC的情况下,压测图形的秒级监控会形成一个锯齿状。另外在GC的时候,还有可能TPS就会掉0,掉坑,这种锯齿状的处理能力可能会造成线上的问题,所以压测监控一定要按照秒级监控。另外一个要注意的是,发压端与被测端对比。有时候出现这种场景:研发人员很自信:我的监控数据很好、响应时间OK、可用率100%,但是从发压端来看,发压端真正是用户感知的,收到的响应时间跟慢,也有很多time out,但是发压端的监测是感觉不到的,这样的问题就需要再定位这是通过对比出来的。这种问题的原因有很多,比如网络传输,序列化和反序列化、系统资源的抖动等等,这就需要具体问题具体定位,这个对于初级性能测试人员是往往容易忽略的问题。
讲完工具,再看看京东是怎么做链路化压测这种实践的,怎么利用forcebot平台做全链路压测的?首先定义一下压测的目的:对容量整体的评估,对资源再分配;第二点看压测方式:我们的军演是把压力机部署在CDN上,通过外网模拟真实用户,这样的好处是压测链路比较长,包括公司负载均衡、网关、安全都压到了,但是这套实施的难点就是数据流量的识别,到底哪些是测试数据,这是千万不能影响线上环境的,也不能给线上带来脏数据,数据的改造是每一个公司都要面临的问题。京东做这件事做了一年多,到现在也继续在持续改造着,上次讲完很多朋友都在问京东是怎么做的。我再来解释一下,最重要的一点是在公司领导层面达成一致。为了一个质量的改进或者质量的验证,可能会牺牲业务开发的时间,公司高层一定要达成一致意见后再往下推,在推的时候建议各个业务条线架构师配合,如果让测试人员做技术改造可能有点困难,但是测试人员比较适合做推动者和倡导者,因为改进的是我们的质量,是跟我们的工作息息相关的,可以提高测试效率和效果。最后一定要每周做例会、回顾、周报什么的,通过项目制,把系统改造作为很重要的事推进下去。
如图,我们是这样做的打标流量识别,首先在测试之前先准备一些测试数据、测试帐号,发压的时候需要打标,因为是模拟用户行为,所以一般都是HTTP请求,第一层服务识别这个标再进行RPC透传。这也是看业务系统如何改造,如果有能力的话最好在RPC框架基础上做流量识别、流量隔离。如果不方便从业务层面改造识别也是OK的,改造方式其实有很多,有可能配置一个影子库、影子中间件,有可能就写进一个打标的数据,事后再进行清理,这些都是可行的办法。在京东我们也是每一条线处理的方式有区别。
最后看链路化压测,每年的双十一、618都会做链路化压测,这个压测前前后后可能从准备到最终实施要一周多的时间。准备的时候要确认压测范围、确定好流量到那个环节就会停止住了,或者说是有哪些入口、哪些系统需要参与压测对于中台来说,是否需要补量压测场景的设计和评审、数据的准备,这就需要花很长的时间了。
第二步要在压测前,把我们的脚本还有我们的数据准备好,压测池的资源分配、压测数据提前录制好、准备好,分发到压力机上,因为这个数据往往都是很大的文件,线上录制也好,构建生成也好,要提前同步到压力机上,实时拉取可能会影响效果。还要准备好我们要压什么、紧急预案是什么、发生问题第一联系人是谁等等,在压测前一天晚上,要准备好小流量的验证,可以先试压一下,最后再线上流量的验证。实施阶段,我们一般是线上扛量用一个机房,压测用另外一个机房,压测流量需要适时调整,还有降级演练,最后还要把压测成绩单进行汇总。这个步骤每年都会很费时、很费力,从数据准备到脚本验证再回放,其实回放可能不会很长时间,但是前期的数据准备、构造会很耗时。
这就说到全链路的一个痛点,也就是我们为什么做流量回放,这是今年我们想的一个平台2.0的演进。
作为平台开发来说,链路化压测做完以后下一步做点什么?业界都会想到自动化、智能化、常态化,这样的 title很大,但是怎么做到呢?我们首先想到从数据的准备到发压做成自动化,就是流量的录制和回放。不再需要写脚本和准备数据,这样从真实环境上录制流量,当然这个前提是,业务改造一定要相当的完备了,我们写的流量到底能不能去识别?这个是很必要的。其实做流量回放在京东也是有背景的,在618今年也发生这样一件事,之前军演准备的时候,我系统处理的TPS可以达到很高,但实际上在流量高峰的时候,发现还没有到达这个TPS,系统资源CPU就已经耗尽了。后来,分析原因还是压测场景设计的不到位,比如,同样是一个查询用户的接口,用户信息多和用户信息量少,这个对于系统来说处理是不同的,我们准备压测场景还没有完全覆盖住真实的线上状态,所以这也是驱动我们必须要做这么一件事的原因:真实的线上的流量回放。
另外一个方面,刚才也提到了,流量回放不仅仅是单机对于单一应用的回放,是中台和前台体系所有入口流量通通进行回放,这个在回放过程中天然形成一个配比关系。以往我们的配比关系都是专门分析出来的,例如同一个系统里的三个接口,配比1:3,是通过分析日志,或者分析以往的流量得到的。而流量回放的时候,这个比例是天然形成的,不用再参考、不用再设计了。这是一个巨大的方便优势。;
第三是切实做到提效,我们想做常态化的压测,想把这种军演、链路化压测成为常态化,除了系统改造,还要实施的很方便,录制数据不需要研发配合,不需要在应用端抓log,不需要改java代码拦截流量数据,回放的时候也不需要再写脚本了,这是一个常态化或者说自动化的前提。其实从入口上录的流量还有一个好处:不再依赖于被测系统,不再依赖于线上应用。以往我们对线上应用的log录制的话,在大促的时候可能是不敢打开的,因为会影响线上的性能,但是如果我们从入口交换机分光出来的流量对业务是完全无侵扰的,可以随时随地的录,这也是它的好处之一。
最终达到这样一个效果,线上流量录制,然后放在数据中心再做压测流量的回放。
如图,这是我们实现的一个架构,其实我们也在实践阶段,方案并不是很完备,更多实现细节我也就不再详细的介绍了,主要还是这样几个模块,抓取模块从分光器上把流量抓取,到一个性能非常好的消息队列里面,之后再增加一个安全模块。线上数据安全性问题是非常重要的,在互联网行业,安全再怎么做都不会过分,因为用户安全可能会有各种各样的问题。最后落盘到京东一个分布式系统里面,大家可以用自己公司的文件系统,这个加密后的数据也可以放到内网回放,甚至用于功能回放都是OK的。具体怎么用,依赖于域名的过滤,根据自己的系统适配就行了,回放的时候可以用个固定的脚本,把录制的东西当作参数化文件进行发压。
最后做一个比喻,流量录制回放相当于蓄水池的概念,用几个小时的时间把线上数据录制下来集中存放,然后再用很短的时间集中释放,达到模拟洪峰来临的效果。今年在双十一备战上我们的流量录制已经在开始用了,效果还是可以的,很多业务的配比关系直接用这样的真实数据了,业务的测试也比较轻松了,不用再写很多脚本了,也不用再向研发要这种参数数据了。
最后有一点想说的是,“醉里挑灯看剑,梦回吹角连营。”线上各种各样的状态牵动着测试人员的心,希望大家还是用自己的技术改变公司的质量文化、质量氛围,从自己做起。谢谢大家!