打破传统的质量评测手段
童庭坚(PerfMa 技术部CTO)
《打破传统的质量评测手段》演讲
TiD2020质量竞争力大会邀请了PerfMa 技术部CTO童庭坚为参会者带来《打破传统的质量评测手段》精彩演讲。
童庭坚从“为何故障防不胜防,不断增强系统的反脆弱性,在不确定性中获益”三部分,阐述打破传统的质量评测手段,增强系统稳定性。
(一) 我们总会有这样的顾虑
1. 顾虑一:有做性能测试,但仅代表实验室
我们有比较完善的性能测试规范和手段,对于重大项目变更发布前都会进行性能验证,但因为环境、数据和生产的差异,测试结果仅能代表实验室数据。因此,即便有正式的测试报告,运维人员依然会为版本迭代上线后或重大营销活动的容量和性能担忧。
童庭坚讲到这主要是两大原因:一是环境差异,二是场景差异。
2. 顾虑二:我们项目紧急,来不及做性能测试
随着业务需求迭代速度加快,很多项目发布周期短,再加上测试资源不够用,所以发布前大部分变更只做功能验证,而上线后系统响应很慢,或业务不可用的情况难以避免。
3. 顾虑三:平时生产水位很低很低,从没出现过这种情况
考虑到生产容量的安全线,运维部门通常会通过设备冗余手段来保障。所以,平时设备水位会非常低,以应变不确定性大流量业务场景。事实上,这种手段也是防不胜防。
不论是业务场景的变化(线下业务模式转到线上),还是业务量的突增,都可能会导致系统出现用户访问卡顿甚至无法响应的情况,比如:疫情期间线上零售(买药/买口罩/买菜)、直播、教育等行业明显出现此类情况。
(二) 系统稳定性为何如此不堪一击
开发、架构、运维,测试,都会担心系统的脆弱性。那么我们如何去保障整个生产的稳定性?
系统的性能、可靠性能力都将直接影响到系统稳定性,我们把这次测试归属为非功能测试。非功能测试不同于功能测试,功能偏重于对业务的理解和测试方法,而性能、可靠性测试还需要有足够的架构理解和性能分析及调优力,业内在非功能测试(尤其是性能和可靠性测试)上投入大的企业为数不多,这也就意味着不可能建立较为完整的性能保障体系。所以,生产系统的稳定性风险随时可能爆发。
(一) 什么是反脆弱
1. 反脆弱是什么
反脆弱是脆弱的反面,脆弱的反面并不是坚强或坚韧。坚强或坚韧只是保证一个事物在不确定性中不受伤,保持不变,却没有办法更进一步,让自己变得更好。而脆弱的反面应该完成这个步骤,不仅在风险中保全自我,而且变得更好、更有力量。做一个类比的话,坚强或坚韧就像一个被扔到地上的纸团,不会摔坏,但是也只是维持了原貌,这还不够。
2. 反脆弱的目的
和纸团相反,乒乓球扔到地上非但不会摔坏,反而可以弹得更高。乒乓球拥有的就是脆弱反面的能力,也就是反脆弱。反脆弱是塔勒布定义的一个全新概念,和脆弱刚好相反,指向了另一个方向,指出事物在风险和不确定性面前并不是束手无策的,完全可以扭亏为盈。
(二) 打有准备的仗,业务井喷之下,依旧丝般顺滑
IT系统的反脆弱能力不是说高流量下通过限流保护自己不被击垮,而是让生产系统的架构具备弹性能力,更像是提升系统反脆弱能力。
系统的反脆弱能力,可以从两个方面考虑,一个是防御能力,另一个是是应急能力。防御能力包括架构设计、研发实现、质量评测。应急能力包括监控、定位、止血及解决能力。
如何去提升系统的反脆弱能力?童庭坚重点介绍了能力体系中的一种方法:全链路压测。
(三) 为什么“他”的反脆弱性可以历练得如此之强?
童庭坚介绍了自己在阿里经历过的双11期间从提心吊胆、只怕意外到丝般顺滑的3个阶段。
2012年到2014年是提心吊胆阶段。在双11之前,线下对系统进行性能相关的压测,运维同学在生产做引流压测,这两种手段结合对系统的容量进行评估。但事实上,在2013年前的多届双11经常会有各种各样的故障出现,尤其在双11业务高峰时,出现用户体验下滑的情况。
在2014年上半年,当时各业务线架构、中间件、DBA、质量等团队共同落地了全链路压测方法。虽然2014年到2015年期间有了全链路压测方法,但一直处于容量验证的阶段,因为仅仅验证容量是不够的,担心出现意外情况。比如业务场景预判有偏差或其他未验证到位的隐患暴露,可能就会影响系统可用率。
2015年到2017年是丝般顺滑阶段。基于全链路压测方法,实现生产重大变更、预案的演练。全链路压测方法不单单验证性能,其更大的价值会在系统的健壮性和可靠性历练上。在双11的真正业务高峰来临时,各类场景都经过演练,做到胸有成竹的信心对技术人而言,就可以理解丝般顺滑了。这体现了全链路压测方法的整体价值。
前面提到的“从传统质测局面中突围”,其实指的就是全链路压测方法。
(四) 一种“从传统质测局面中突围”的反脆弱能力提升方法
全链路压测方法
全链路压测方法起初在蚂蚁经历了几个阶段的演变,在12年前基本的测试方法还是线下做单系统压测,针对评测出的问题进行分析和优化。这种测试方法可以发现单体系统本身的性能瓶颈。由于验证整条业务链路上的系统集成性能表现,所以生产出现一些集成情况下的性能容量问题仍然常见。
2012-2013年我们在实验室环境中构建了全链路系统进行了业务链路系统回归,由于蚂蚁的系统较多,我们根据系统的等级划分来确定核心业务链路回归范围。对于核心链路以外的系统,可以采用挡板模式做服务模拟。通过这样的方法针对每个日常迭代版本进行实验室评测,当时我们把这个方法叫关键业务链路回归压测。
事实上,关联业务链路回归压测毕竟是在测试环境,和生产的环境差异较大,压测的结果对运维部门而言参考度并不高,所以,通常在营销活动前,运维人员会在生产上做大规模的引流压测(通过真实流量转发的方式实现引流),这也是早期在蚂蚁金服用的最多的容量验证手段,就是引流压测。
由于引流压测只能针对单个集群间的流量转发,所以验证的方式和实验室的单系统压测类似,只是引流压测在生产是真实环境,不存在环境差异导致的仿真度问题。但弊端也很明显,所以希望做全链路级别的生产压测。
生产压测有几大不可缺失的能力。包括:流量模拟、流量识别、风险识别、风险熔断等,这些能力的目的都是考虑如何规避生产环境压测所带来的风险。
生产压测的顾虑
在阿里有两套全链路压测体系,一套是淘系,另一套是蚂蚁。因为电商和金融存在比较大区别,金融行业以稳为主,全链路压测的目标是保障稳定性,但是它也会带来稳定性风险,所以金融行业落地该方法是一个比较大的挑战。
全链路压测方法从多地域模拟真实用户流量对生产系统施加压力,但它不仅仅是一个压测工具,还需要能实时感知到生产系统承受压力时的风险大小,以决策压力调度引擎应该降流量还是直接熔断,决策的精准度和实时性对技术人员也是巨大挑战。
3
全链路压测-风险防控体系
如果我们采用传统的性能测试方法在生产上实施压测,量进入生产后,数据将会落到生产数据库中,假设,压测数据跟生产数据是相同的,这种情况就会造成真实用户数据污染。所以,对于生产压测,首先要解决的是生产风险防控体系。这里我们挑几个关键能力进行介绍。
流量染色
压测工具模拟各地的流量将进入生产环境中,与真实业务流量运行同一套环境,所以流量染色也是生产压测最重要的技术之一。假如在压测过程中,压测流量身份出现丢失的情况,就意味着应用无法识别是测试用户行为还是真实用户行为,其结果就是造成数据污染。
日志隔离
流量染色时大前提,染色后可进行日志的隔离。日志隔离的目的是为防止测试流量产生的日志和生产流量产生的日志相互混淆。因为如果日志混在一起,并且没有明确的标识区分日志的话,很可能会影响基于日志的业务监控或者离线BI分析数据。比如一个账户频繁的登录,其实是由于压测模拟登陆,离线端BI分析出这个账户是活跃用户,这种情况下可能会造成营销成本的浪费。
数据隔离
数据隔离和日志隔离手段类似,但数据的污染比日志污染更为严重,数据污染将直接影响到最终用户。
风险熔断
有了流量染色、日志隔离、数据隔离,做到了不污染生产环境的任何资产,前面我们提到生产压测对生产的稳定性也会有影响,所以,风险的感知与风险的熔断能力是必不可少的。
① 风险防控体系-数据隔离能力
数据隔离能力有多种实现方式,一种是通过侵入式在中间件层面进行改造,或者直接在应用系统当中进行改造业务代码,实现数据的路由、数据的隔离。
另外一种手段是通过字节码技术增强数据访问层,比如说rpc框架的关键数据路由收口处。
数据隔离能力有三种实现方法:影子库、影子表、影子数据。从影子库、影子表到影子数据,代表着仿真度从低到高,风险从高到低。
影子库采用独立的数据源实现库级别隔离,比如说在应用上实现两套数据源。通过流量标识来决定路由影子库连接,生产流量选择生产库连接。
影子表技术,采用SQL转换实现表级别隔离。对于DB而言,影子表技术的运维成本和风险会高于影子库,影子库可以进行CIUD操作。但是影子表情况下,误操作的风险较大,可能因SQL编写错误而导致误操作真实用户表数据。
影子数据是采用字段标识实现在同表不同记录级别隔离。比如有一个字段是标志这条记录是测试数据还是生产数据。但这个方案的运维成本和风险会有更高挑战。
数据隔离方案的选择取决于企业IT系统设施的成熟度,需要根据每个企业的现状来选择合适的方案。
② 风险防控体系-压测管控能力
在生产系统上建设相应的风险防控能力后,全链路压力发起毕竟发生在生产环境,和我们日常生产运维变更一样是高风险操作,所以压测实施需要有合理的流程进行控制。以下按照风险可控的最高要求对压测风险的管控阶段进行阐述。
第一,由系统测试人员指定压测场景、压测目标进行提测,全链路压测平台将自动进行冒烟和预热。冒烟这个环节非常重要,既可以验证业务功能也可以检查压测风险。比如,生产发一笔流量,平台把这笔流量经过的全链路系统涉及到的所有日志、数据、缓存都反馈到平台上,并基于一定的规范进行校验是否有污染风险。比如,影子表的规则可以在表后加上test,影子Key也同样可以这样做。如果冒烟存在风险则不允许压测。
冒烟通过以后进行预热。预热也可以设定一些规则,比如说允许提测的场景1%的流量进行预热。预热的目的是在冒烟基础上进行小规模流量验证,避免直接大流量压测而产生风险。
冒烟和预热通过后即可进行限定流量的生产压测,压测的目的是发现问题,也就意味着可能随时出现生产故障,因此还需要有风险熔断能力。熔断是基于监控数据进行决策,它会依托大量的监控数据进行实时分析。比如,从用户体验或应用系统承受压力角度进行分析。应用系统在承受不同的压力后的资源消耗和执行效率大有不同。
只有监控分析能力有一定成熟度后,风险熔断才有好的压测依据,也就是说生产压测中我们能够保障在用户能感觉到系统异常之前,快速做风险熔断决策。
4
全链路压测-故障演练能力
生产中存在各种不确定性因素。我们可以通过故障演练或者可靠性测试挖掘这些风险。
故障演练通常和压测一起进行。测试环境的故障演练测试,通常是在压力发起的同时,模拟断网、数据库停机、应用僵死的现象。还记得早在10年前,测试人员在发起压力后由机房工程师进行实际的异常模拟操作。
而在全链路压测方法中,我们可以将这一能力集成到平台中,实现自动模拟某个接口变慢、流量阻塞等。比如,A系统调用B系统,可以模拟B系统变慢或无响应后会不会引发A系统雪崩现象。
5
全链路压测-性能基线分析能力
在全链路压测方法上我们还可以做一些延伸,可以将不同版本下的性能数据形成基线,通过版本性能差异分析挖掘一些累积性问题。比如系统的处理能力随版本迭代不断小幅度下降,或系统依赖关系逐步复杂后的性能隐患。
举个例子:某系统的新增商品业务设计ABC三个应用,老版本的响应时间是1秒,假设ABC三个系统的耗时都是333毫秒。新版本变更后,A系统的耗时从333毫秒变成是500毫秒,BC系统分别是250毫秒。从传统的站在用户体验的压测方法角度看,用户体验似乎无影响。但实际A系统存在较大性能隐患。
再举个例子,某业务系统改造前单笔业务调用redis2次,改造后调用10次,由于单次redis调用耗时非常低,对整体的业务响应时间影响不大,但在生产业务量大的场景下可能会出现redis容量瓶颈。因为通常redis集群为公共设施,会服务于多个业务系统,从而引发严重生产故障,类似的情况早期在企业当中很常见。
因此,业务系统的性能和容量基线跟踪和差异分析能力能够有效揭示稳定性风险。
6
形成全链路压测能力体系
上面我们更多在介绍全链路压测的各项能力,在能力的基础上,我们可以打通整个持续集成,将全链路压测方法变成可持续的能力,降低版本变更后的持续回归成本。
7
左右赋能,为IT系统稳定性护航
可持续的全链路压测能力体系向左可以赋能给研发,在开发过程当中,研发人员可以自助评测性能,这样既可以减少开发过程中不断调优后对测试角色的依赖,提升整体效率,研发人员还可以通过评测规范和能力提升性能意识。
同时,整套能力向右可以赋能于运维,运维人员可以利用全链路压测能力进行促销活动路演,识别活动下IT系统的整体性能和容量,以及结合故障模拟、变更演练来验证系统的健壮性。
(一) 夯实底盘,不断完善能力体系
结合于行业性能测试体系的现状分析,我们将其划分为为自测型、驱动型、规范型、敏捷型、赋能型五个阶段的成熟度。目前,较多企业处于驱动型和规范型阶段,部分中小型企业可能处在自测型阶段。
自测型,无性能测试团队,开发自行测试后上线。
驱动型,有性能测试团队,项目或需求驱动测试。
规范型,统一性能测试规范和标准,变被动为主动。
敏捷型,性能评测能力体系化、平台化,把能力赋予开发人员自测,高效协作。
赋能型,形成一套完整的性能评测的体系,并赋能研发和运维。
所以夯实底盘,不断完善能力体系是至关重要的。
(二) 保障活动,让不确定性“转”确定
全链路压测能力在阿里以及一些一线互联网企业,已成为促销活动性能容量保障的神器,活动前演练设定的防线保障确定性业务场景稳定,活动前演练设定的预案保障不确定性业务场景的稳定。
(三) 抓住机会,在不确定性中获“益”
受疫情的影响,很多企业业务模式由线下转线上,造成线上流量剧增。比如在线教育、医疗健康、协同办公、视频会议、金融领域都有这一变化。所以提升整个系统的反脆弱能力,可应对未来的不确定性,并在不确定性中获”益”。