相比传统的单体应用架构,微服务架构具有更多优势,但微服务同样不是万能的。它的许多优点同时也带来了明显的缺点,比如单个微服务虽然编译得更快了,但微服务数量却翻了数倍。再比如单个微服务可以针对热点服务进行单独扩缩容,但也就需要投入更多的运维成本,等等。这也使得微服务架构在架构设计、团队协作、测试环节等层面引发一系列挑战。
我们知道,“越晚发现的问题,修复的成本也就越高”,如果在项目开始对这些挑战处理不当,项目后期也将很难弥补,即使弥补了也容易采取临时方案,而这些最终都会体现在软件产品或服务的质量上。
那么,对于微服务架构所带来的挑战,我总结为以下三个方面:
微服务的重点是将架构分解为粒度更细、更易管理的服务,但这意味着要引入更多的服务间依赖关系。微服务实践最常见的错误之一是把微服务设计得过小,以至于微服务数量泛滥,而这通常会导致任何服务都可以随意调用任何其他服务的情况。如果没有好的设计,那么系统的复杂度就会与微服务的数量成正比(极限情况下,N 个服务,会存在 N(N-1)/2 个调用关系)。
微服务架构的关键不仅在于具体的实现,更在于合理地划分服务边界,与组织架构是否相匹配,以及相应配套的技术设施,如持续交付、DevOps、去中心化实践等。
因此,只有通过谨慎的服务架构设计才可以降低系统复杂度。 你不能只像以前做单体应用服务测试时那样只关注系统整体实现了什么,还需要关注系统架构设计、模块、服务划分、每个服务实现的功能、上下游调用关系和调用方式等。
系统依赖性的增加会给团队协作带来更大挑战,这里我所说的协作工作包括但不限于开发、联调、测试等。
在传统的单体应用开发项目中,当一个团队(即使规模很大)共同协作开发应用程序的不同部分时,可以有一个共同的项目管理计划,包含范围、时间、人物力资源、质量、风险等,并且当出现潜在的技术冲突时会有架构师这样的角色来规避和解决。
而在微服务应用中,不同微服务常由不同团队开发和维护,而每个微服务可能会有不同的客户要求、开发周期、开发进度和交付期限,并且没有或只有较弱的总体项目管理。当服务频繁进行改动或版本升级时,很容易出现跨微服务功能不可用、版本不兼容或延迟实现等问题。协调软件的整体开发会变得异常困难,你也很难找出一个空闲时间窗口来对整个软件进行全面的测试。
因此,产品及研发人员需要各种沟通,以此来了解不同团队中微服务项目的开发进度,沟通成本大不说,而且容易有错漏。在其中,因为测试人员是产品交付的最后一道关,任何在前期遗留下来的争议或错误,都会在测试环节放大或暴露出来,进而间接影响项目研发效率和质量。比如到了测试环节才发现依赖的服务不能按时提测,你只好用 mock 的方式模拟该服务。这种情况会导致你测试效率降低,且发现不了真正的问题。
在这里,建议要基于微服务的特性建立相应的流程规范,比如把可能产生的风险前置暴露出来并做提前应对、重视多方评审环节、根据问题驱动流程规范不断优化和完善,等等。这些内容也将在课程的后续部分详细解说。
单体架构下,通常使用集成测试来验证模块间的依赖是否正常,而服务数量并不多,搭建一套测试环境的成本不高。但在微服务架构中,无论是服务、模块还是层次之间都存在复杂的依赖性,想要单独测试某一服务,需要其他服务的依赖关系。你要验证的不仅仅是某个服务本身,而是某个业务场景所涉及的服务链路,且它们又同时依赖着其他服务,归根结底你需要的是整个业务链路上的所有服务。
在同等规模的团队,微服务的数量可能是单体应用服务数量的几倍甚至是数十倍,为每个服务搭建基础环境(运行环境、数据库、缓存等)并进行部署、配置的成本也对应增加。
这就造成:
微服务架构下,可独立部署的服务多,集成测试的反馈周期依赖较多服务,这将导致定位问题的时间变长。同时,由于微服务由各自团队独立部署,测试环境的不稳定也更容易导致测试执行失败。为了编写有效的集成测试用例,质量保证工程师应该对软件所提供的各种服务都有全面的了解。
微服务架构中,每个服务进行独立地配置、部署、监控、收集日志,对于调用链路较长的场景,排查问题时需要进行链路调用分析,逐步排查,其成本呈指数级增长。
除了上述挑战外,微服务架构的复杂性使测试工作本身变得更加困难。测试挑战包括测试环境、测试技术与工具、测试方法以及测试结果。
通常来说,一个业务有多个微服务,每个团队的测试工程师仅对其负责的微服务负责,没有统一的角色来管理整体的测试环境。这种情况下可能出现一个微服务不可用时,依赖它的服务均无法正常提供能力,进而会导致其他 QA 人员的测试任务阻塞。基于此,常见的做法可能是分时段使用环境或者维护多套测试环境。但如果所有 QA 团队对测试环境分时段使用,相当于轮流进行测试,那么整体的测试效率会低很多。如果各自维护一套完整的测试环境,那么诸如“谁来修复”,“谁来协调”和“谁来维护”等问题可能无法得到解答,且会带来较多的服务器成本和沟通成本 。
微服务架构允许为每种服务使用不同的技术基础,这可能导致需要使用不同工具来实现相同的功能,如使用不同的编程语言、数据存储与同步、部署环境等。技术的多样性会导致 QA 人力资源难以培养或增加人力成本,同时很难构建和维护一个涵盖所有内容的良好测试环境。
直接用单体应用架构下的测试方法来测试微服务并不可行。单体应用架构下,测试方法往往需要理解用户需求的背景,用端到端测试的方式对业务功能进行整体验证。
而在微服务架构下,虽然端到端测试可以在软件开发生命周期的后期起到作用,但因为测试对象发生了非常多的变化,需要对测试对象进行重新分析,那么就需要对测试策略进行整体变更,也就是说,原有的测试方法不再完全适用。
微服务通常是分布式系统,这意味着服务之间通过网络调用进行通信,那么数据在网络上传输时不可避免地会出现网络延时、超时、带宽不足等因素,这将导致不稳定的测试结果。主要表现在如下方面。
上述,我介绍了这么多微服务架构对软件质量保障工作带来的诸多挑战,你肯定坐不住了吧?不要担心,这些挑战都有对策。任何新技术的引入和架构的演变都在解决当前痛点问题的同时引入新的问题,那么这些新的问题也将不断变成痛点被逐个解决,这是技术演化的必然,也是互联网革命的核心(唯一的不变是变化)。
任何时候挑战和机遇都是并存的,通过掌握恰当的测试策略和质量保障体系来应对这些挑战,那么你就比同行(横向比较)或过去的自己(纵向比较)具有更多的竞争力和优势,自然也会有更多的机遇。
与单体应用架构相比,微服务架构的诸多好处,使得它成为主流是必然的。与此带来的挑战,我们应该如何思考和分析,找到恰当的测试策略,构建全面的质量保障体系呢,我将在下一课时介绍。