前言
近几年,互联网项目很多都有从单体服务转变成微服务化的趋势,尤其是一些架构复杂,业务比较广泛的项目,微服务化是大势所趋,可以解决独立构建、更新、运维等一系列问题,从而解放生产力,促进交付效率和质量。
目前网易云容器服务团队以 DevOps 的方式管理着30+微服务,如图所示,容器服务项目微服务化特征明显、层次划分清晰:
从第一个层面来讲,线上及 线下环境多样化和复杂性决定了构建部署次数的频率,据不完全统计,线上线下每周构建部署次数 400+。开发人员在每个迭代(两周一迭代)提测前每个模块在联调环境至少更新2到6次,测试人员在每个迭代提测后需要每个模块至少更新2到6次,才能达到发布标准。好的构建、部署工具可以提高构建部署时间效率从而节约开发人员和测试人员的时间,达到快速交付的目的。因此找到好的构建、部署工具和平台的重要性和优先级都是第一位的。
另一个层面,容器化服务在提测模式,上线模式、分支管理跟之前都有很大的不同,测试团队需要针对容器化服务特点在提测模式、分支管理、质量评价方面做出一些适配和优化,以适应容器化及微服务架构的特点,将完整的容器化持续集成流水线模式引入,以及镜像质量评价打入元数据的实践探索。
最后一个层面,微服务化的项目对测试的要求更高,体现在测试范围更广了,测试深度也更深了。例如网易容器云平台的微服务化实践(一)文中提到的从主工程平滑拆分出用户服务的例子,一次拆分等于之前关于用户服务内部调用的流程都变成facade+http接口调用。简单来说接口个数是翻倍的增长(内部逻辑拆分成http接口),更专业来说是分层测试的模式进一步体现出来,这样就使得测试范围就更广了。其次不同的微服务场景和特点不同,需要测试分析更加深入,测试策略更加有针对性,才能全面覆盖微服务架构下的多种服务类型。对测试人员的能力、测试平台及工具、测试效率要求都更高,在这方面的深入探索很有必要,目标是更好的进行质量+效率的全方位保障工作。
下面具体从以上三个层面来看容器服务的测试团队如何解决这一系列问题和挑战的。
一、构建、部署方式在微服务化架构下的实践
OMAD服务部署时代:在本年度Q3季度,容器服务的大部分web服务还是使用OMAD自动部署平台使用构建机器构建并远程部署至目标机器。
如图所示,用户通过UI去创建部署任务,并且触发构建和部署动作完成命令下发,构建机器得到命令后按照集成模板生成工程文件,下载源码、编译并且打包上传nos;目标机器通过agent服务获取部署安装包并且替换模板属性,启动服务。
这个系统在微服务架构不明显的项目中还是比较好用的,但是一旦服务数量增长的很大,并且涉及到多团队多人员去同时构建部署时就会有一些弊端。比如构建机器多任务并行时延,nos上传和下载时延在服务数量同时构建更新时效率会变低。另外多人同时操作同一个服务的构建和部署,有可能会造成冲突导致构建失败。这些问题都不能有效解决。最重要的一点是,构建部署环境强依赖于目标机上的环境配置,例如jdk和tomcat的版本,这样在线上线下多环境复杂场景下,会导致多环境下同一服务表现有可能不一致。也由此引入了容器化服务时代。
DevOps容器化本地更新时代:
将服务容器化需要解决两个问题:第一个问题是配置文件与代码解耦,可以使用docker container启动的时候的env环境变量方式传入,也可以将配置数据服务中心化,目前两者兼有。
第二个问题是构建出来的镜像到目标运行机器之间的传递如何来做,目前是采用网易云容器服务本身在线上提供的镜像仓库来存储和拉取。当然也可以直接使用scp等操作在构建机器上将镜像直接传到到目标机器上。
构建及部署操作分别在构建机器(可多台)以及目标机器上通过ssh登录shell命令和脚本执行的方式操作。这个阶段是本地更新时代,操作流程如下图所示。
这种方式可以解决OMAD时代的多任务并行阻塞问题,以及多人操作构建部署的问题(构建机器多台,另外即使是一台,由于是脚本化构建,完全独立进程,互不影响;部署操作只需要更新目标机器的pod.yaml模板中的image字段即可,几乎不会造成冲突,即使冲突也以最近一次更新的镜像version为准更新下载镜像并重新启动容器)。并且可以解决不同的目标机器上环境不同导致的服务表现不同,因为每个服务都运行在标准化的容器中,该容器预置的tomcat、jdk等依赖包都是完全一模一样的。
目前在开发人员和测试人员的合作下,线上环境已经大部分都采用这种模式部署,线下演练环境由测试人员更新成这种本地更新模式,尽量保证演练环境和线上环境一致性。
DevOps容器化集群管理更新时代:
在本地更新部署模式下如果想更新环境就需要ssh登录到多个目标机器上更新,另外部署完的模块不能根据需要迁移目标机器,这些问题在最近几个迭代中线下环境的联调环境以及测试环境进行了改进,即转变为集群管理更新模式。所谓集群管理更新模式是指将目标机器分别独立去使用kubelet监控管理转变成注册到kubernetes master上去管理。在dashboard上调用创建deployment来启动对应微服务的部署与更新,可以可视化的查看部署进度和状态,以及可以动态的指定服务部署的目标机器,以便于一台目标机器宕机快速的从另外一台目标机器上拉起服务的场景。
最近在测试人员将线下测试CI环境更新到这个模式以后,测试人员普遍反馈更新操作比以前方便了。构建操作也可以省去,当开发人员在联调环境自测完毕后,测试人员直接在dashboard获取到开发提测的最新镜像地址,替换镜像地址即可完成服务升级更新,可以开展测试,大大降低了测试人员重复打包、连接目标机器等繁琐的动作时间。
集群管理更新模式如下图所示:
集群管理模式在线下实验稳定后逐步升级至演练环境以及线上。目前存在kubelet升级或重启会导致目标机器上全部容器重启的风险,需要进一步解决及评估风险。
二、微服务化架构下镜像化提测全流程实践
容器服务项目测试团队针对微服务化架构本身结合测试全流程提出了一套完整的解决方案,包含镜像提测、容器化持续集成建设及质量评价全流程的一套方案及实践,从多角度涵盖微服务化的项目从开发、提测、上线、质量归档等全部环节,从而打造质量+效率的全方位保障工作。
镜像提测模式引入
目前容器服务线上线下大部分服务都由代码发布转变为容器发布,而且通过配置参数环境变量方式传入容器以及配置数据服务中心化等方式支持了镜像多环境发布,这样天然就带来了遍历。即多个环境可以使用同一个镜像部署运行服务。测试团队综合评估效率、版本可追溯的因素,提出了镜像提测的方案。即开发人员由提交commitid给测试人员的方式转变为提交镜像tag给测试人员,一方面可以省去测试人员自己构建代码,更新环境的步骤,另一方面,通过镜像版本化管理以及新引入的质量评价打入镜像元数据等手段来归档提测后的镜像,可以快速追溯到不同质量版本的镜像记录。
代码提测模式如下:
开发人员开发自测完毕后,告知测试人员git提交commitid,由测试人员构建打包,并且部署到线下环境,如果有bug的话,修复要以后需要再次构建打包部署。并且劣势是只能往前增加逻辑,不方便回滚。一旦合入的代码如果想回退或者拆分就很难操作。另不方便排查引入新增的问题的提交和版本,质量评价只能按迭代而不能按提测版本,一旦有问题只能全量回退而不能回退某些特定提交。
下图为代码提测方式的流程图,黄色代表开发人员完成的内容,绿色代表测试人员所做的动作。
镜像提测模式及质量评价打入镜像元数据:
为了更好的追溯镜像版本的质量数据,容器服务的测试团队建设了一个跟jira平台打通的质量评价及归档工具,可以实现在jira上评价的版本质量自动关联到特定版本的镜像元数据中并归档到镜像仓库中。根据评价的内容判断镜像是否可以满足上线标准。后续追溯历史版本也方便快捷。
质量评价打入镜像元数据与提测及上线的流程图如下所示,黄色代表开发人员完成的内容,绿色代表测试人员所做的动作,其中触发jenkins job是jira回调事件自动触发的,不需要人工参与:
容器化持续集成建设及质量评价全流程建设
除了提测模式转变,手工测试完然后质量评价自动打入镜像以外,我们还在线下建设了多个微服务的容器化持续集成及质量评价pipeline建设。目的是为了将静态代码检查、单元测试、容器化构建部署、自动化接口测试、覆盖率统计、测试结论自动打入镜像整合成一套流程,可以满足从代码提交到自动化测试到自动发布及结论归档的全流程服务,适用于接口比较稳定、单元测试建设良好、模块依赖少的微服务模块。
目前已在容器服务团队在中间层服务中建设这样的全流程实践,流程如下所示:
当新增逻辑提交后,触发容器化持续集成全流程的启动。
1. interlayer-UnitTest-SA是使用sonar+PMD的方式对代码进行静态检查并统计出需要修改的问题(Major以上需要上线前修复完毕),并且执行开发编写的单元测试。运行通过后触发interlayer-image-build job。
2. interlayer-image-build主要做了本文第一部分介绍的使用构建机器脚本构建镜像并上传的过程,为环境更新做准备工作。打出来的镜像tag传递到下个job中。
3. interlayer-image-deploy拿到新打好的镜像tag以后,使用本文第一部分中容器化集群管理更新时代中kubelet 更新接口去远程更新目标机器的镜像tag,从而更新中间层对应的服务版本。
4. interlayer-it-test 包含了中间层所有接口测试内容,在环境更新以后自动触发并执行,同时在远程jacoco打桩收集执行覆盖率并回填到sonar的覆盖率统计项中显示。
5. interlayer-buildimage-test是最后一个步骤,当所有接口测试执行通过以后,将测试结果传递到这个job参数中,并且触发重新打包的动作,将测试结果情况打包到被测的镜像元数据中,归档到镜像仓库。
最终测试人员拿到带有自动化测试通过的镜像包,可以继续进行手工测试,继而将手工验证结果通过jira备注触发的方式再次构建手工测试通过的镜像tag,以此版本镜像提供到演练环境甚至线上环境。
理想情况下,假如迭代内容经过评估后只需要完成自动化验证即可上线的,可以直接略过手工测试,将自动化测试通过的镜像tag更新到演练环境和线上环境。相信在不久以后的DevOps时代,这个也会成为现实。这样开发人员就可以直接从代码提交到发布全流程DevOps化了,历史镜像版本也可追溯查看,可做到快速更新、快速回滚等操作。
三、微服务化架构下测试工作实践
容器服务项目的微服务化趋势越来越明显,对测试的深度和广度要求也提升了一个台阶。
容器服务包含的30+个微服务中,大概可以分为两类业务类型的服务,一类是垂直业务类型,就是从上而下完全都是容器服务项目提供的应用支撑业务,例如微服务、镜像仓库,这两大块儿垂直业务都是由多个微服务合作完成的。第二类是横向业务,通过接入其他外部项目应用,或者被外部项目应用调用来提供服务,例如G0网关是提供给其他项目的openapi接口来接入的,G1网关是提供给底层项目的资源调用接口来接入的,internal模块服务是被其他项目调用的,用户服务也是被其他项目调用来完成其职责的。这两类微服务各有各的特点。首先来看垂直业务型的服务微服务拆分后的测试特点。
微服务化的分层测试应对:针对垂直业务型微服务进行分层自动化及端到端自动化
服务拆分后:
黄色块是独立对外的http服务,可以看到,直接可被用户调用的http服务从3个拆分变成7个,这还只是容器服务及镜像仓库提供的主干逻辑拆分,目前容器服务团队项目服务拆分以后已达到30+的独立微服务。服务拆分可以将不同业务的服务范围划分的更明确,更新升级服务也不会造成其他业务的影响。然而对测试人员来说,拆分以后即使逻辑没有变复杂,接口的个数是成倍的增加。
举例来说,创建镜像仓库在拆分之前是存在于web模块接口中的,自动化和手工只需要覆盖web模块的创建镜像仓库接口就可以了。但是拆分之后,web模块保留了代理转发操作、流控等逻辑,真正的业务逻辑移动到nce-repo模块中,以http接口的方式被web服务调用。这样一来,创建镜像仓库接口就有了两个维度的http接口对外提供。其他服务的拆分也以此类推。因此自动化覆盖需要在多层服务级别进行覆盖。直接调用nce-repo模块的接口重点覆盖业务和逻辑维度;从web层调用的接口中重点覆盖端到端场景。目前光是算http接口已经达到上千个接口。还有一些sdk包及独立工具和工程的测试。光靠人肉测试和回归工作量巨大,因此自动化尤为重要。
分层自动化模式:
目前在容器服务项目中已落地实践线下定时触发分层的接口维度测试,确保各个层次的服务都能接口和逻辑维度覆盖到,接口覆盖广泛,目前已涵盖所有http服务模块(web、openapi、api、repo、build、internal、user),定时为每天一次运行。
自动化策略:接口覆盖、参数检查等可以依赖接口文档快速进行的跟开发迭代同步完成,可以确保演练回归、线上回归的效率提升,以及后续迭代的回归效率。逻辑复杂的接口测试取决于接口稳定程度和重要程度后续按优先级补充进行。
下图为jenkins job+TestNG方式涵盖的http服务的定时接口测试,其中下面的四个独立服务的定时接口测试是微服务化后新增的测试job。
端到端自动化模式:
目前已落地实践线上定时触发端到端业务测试,确保用户触发频率高的主干端到端场景能覆盖到,并及时监控,定时为每个场景每小时一次(线上目前已部署10个主干场景+),可以快速发现线上用户可能出现的问题。
下图为目前在线上环境健康运行的端到端业务测试:
微服务化的分层测试应对:针对横向业务型微服务增强mock、加强独立服务逻辑测试、加强专项测试
针对垂直业务分层自动化以及端到端自动化效率显著,针对横向业务,例如G0、G1网关这些本身不提供逻辑接口的服务来说,如何进行有效针对性的测试呢?
拿G0网关举例,G0网关的主体功能及在项目中的位置如下:
如果只基于接口的测试则完全不能覆盖G0网关本身的逻辑,并且接口本身逻辑不属于容器服务的范畴,效率不佳。在这类微服务测试中,测试人员采用mock后端服务、加强独立服务逻辑测试的模式去覆盖。mock后的G0网关如下所示:
G0网关中的认证服务、流控、审计功能通过模拟不同的认证方式、参数组合、场景组合、mock接口加压触发流控、日志检索等方式去进行测试覆盖。在单独的环境下,将大部分依赖的外部服务mock掉,然后进行测试场景模拟以及自动化,在微服务化架构下,是一个测试人员必备的手段。这样可以有效排除掉由于依赖方的异常或不稳定导致的问题,能够专注于G0网关这个服务本身的逻辑和稳定性。
除了基础的功能和逻辑覆盖以外,测试深度不断深入也是微服务化项目的一个必然的要求。容器服务项目测试团队的测试深度挖掘包含多种工具、平台的应用以及专项测试的实践。
微服务化项目的逻辑复杂性决定了测试团队不能只专注于基本功能和逻辑的满足需求,还需要在某些极端情况下验证多个微服务之间合作是否顺畅,例如请求流量大的场景、 服务之间网络异常场景、依赖服务返回值异常的场景,这些都需要在专项测试中完成场景的分析和覆盖。在容器服务项目中,落地了多次专项的异常测试以及稳定性、性能测试。在测试过程中也发掘了不少有价值的场景和异常分支的潜在风险。同时也引入了一些工具和平台,例如性能测试工具、加压工具及平台、异常构造工具及平台、mock平台等。
微服务化后,由于分层测试引入的测试的自动化覆盖率要求就更高,由于专项测试需要的手段更加繁琐,自动化复杂度也变得更高,因此相应的测试执行和自动化时间如果没有更好地方法,时间势必会占用的更高。在容器服务项目中,测试人员进行了一系列的效率提升手段,以解决测试深度广度加大以后带来的工作量增加问题。
微服务化效率提升手段:接口自动化之tc关联以及自动化前移
上文提到,服务拆分以及接口分层化会导致接口成倍增长,自动化必不可少,编写自动化之前往往是在手工测试执行之后开始编写,有时候甚至等到该接口和功能上线以后再来补齐,这样会造成手工测试在多环境反复执行,因为上线前自动化代码仍然没有编写,因此会造成效率低下。在容器服务项目团队中,测试人员引入了自动化前移以及tc平台关联自动化的流程。
自动化前移是指:在开发提测前,测试人员拿到开发接口文档和部分设计文档后就开展自动化编写工作。基于的前提是接口文档全面无变更,这在新版openapi模式下已经成为可以落地的现状,因为新版openapi模式从需求提出开始就要求接口是确定的,较少变更的。因此也助力于自动化前移可以落地。测试人员编写大部分自动化代码后,在提测后可以使用较少的时间调试通过,并且补充少量手工测试,以完成这些接口和功能的测试任务,在代码质量达标以后上到演练环境以及线上环境可以快速的适配自动化代码的配置文件以达到快速回归的目的。这样有效的降低重复的手工多次回归的时间。
tc平台关联自动化是指:我们目前所有的执行集合都是由tc平台 上创建并管理的,即使自动化测试在线下运行以后,仍然需要手工操作对应的测试用例置为成功状态。存在重复的操作工作量。引入tc关联自动化以后,通过在自动化代码case的元数据中加入tc对应用例的id的方式,可以将tc的用例跟自动化代码case关联起来,通过tc上触发自动化的回归并且同时回填测试用例的成功或失败状态,节省手工查看用例跟自动化的对应关系并且置位的操作步骤。
下图为容器服务项目中新版计算需求大部分接口自动化以后跟tc相关联的执行及回填效果:
接口自动化以及逻辑自动化几乎都可以采用这种手段提高效率,但是容器服务项目还存在着一大部分关于UI的测试范围,比如微服务以及镜像仓库的页面也需要测试人员去例行回归。这部分的效率怎么解决呢?
微服务化效率提升手段:前端自动化录制回归
容器服务项目测试团队引入了UIRecorder组件去进行前端自动化录制的步骤。并且将录制方式通过培训、合作调研的方式提供给前端开发人员,这样可以使得前端有样式或者逻辑变更的时候快速识别并且重新录制。
测试人员可以使用前端开发提供的录制脚本结合jenkins job的方式一键回归各环境的前端用例。目前容器服务的前端已经有30+个场景通过脚本录制的方式集成到jenkins job,解放了一大部分的测试人员回归的工作量。
微服务化效率提升手段:mock平台引入
容器服务项目测试团队引入了平台基础服务一组自研的mock平台 ,在进行横向业务型微服务测试工作中,快速使用mock平台去将依赖服务mock掉,并完成微服务本身逻辑的测试及自动化工作。经实践,容器服务项目已使用mock平台构造比自己使用Moco等Mock Server工具构造场景时间大概节约了80%,在异常专项测试以及横向业务型微服务测试执行中大大提升了执行效率。
下图为目前在mock平台已mock化的外部依赖接口:
总结
本文是《网易容器云平台的微服务化实践》系列文章之一,一共从三个层面讲述了目前容器服务的测试团队所做的一系列实践工作,关于容器部署模式、提测模式、容器化持续集成等活动已经在部分模块和服务中有一些已经落地的实践,也一定程度解决了微服务化后测试团队面临的质量效率双重挑战的问题。在后续的测试工作中,需要进一步固化微服务容器化提测流程,质量元数据归档等步骤,并且推广给其他微服务化架构项目团队中。在测试具体工作上引入的一些实践活动效率提升的手段也效果显著,后续需要再挖掘一些增强测试探索的理念和实践,从而为项目的质量保障工作以及打造团队影响力做出重要的贡献。
网易云容器服务为用户提供了无服务器容器,让企业能够快速部署业务,轻松运维服务。容器服务支持弹性伸缩、垂直扩容、灰度升级、服务发现、服务编排、错误恢复及性能监测等功能。
背景回顾:网易容器云平台的微服务化实践
本文来自网易云社区,经作者崔晓晴授权发布。
原文地址:网易云容器服务微服务化实践—微服务测试及镜像化提测全流程实践
更多网易研发、产品、运营经验分享请访问网易云社区。