开发之痛:稳定的测试环境,怎么就那么难 | 研发效能提升36计

简介: 开发之痛:稳定的测试环境,怎么就那么难。对于生产环境,准确、稳定最重要,我们推荐以应用为中心的基于OAM和IaC的实践方式;对于测试环境,隔离、低成本和稳定的依赖是最重要的,我们推荐基于稳定环境的隔离测试环境的实践,复用稳定环境,通过流量隔离和数据隔离来生成测试环境。通过环境建设,我们解决了研发过程中的资源冲突。

image.png

专栏策划|雅纯

志愿编辑|jimmy、吕瑞星

“对于生产环境,准确、稳定最重要,我们推荐以应用为中心的基于OAM和IaC的实践方式。

对于测试环境,隔离、低成本和稳定的依赖最重要,我们推荐基于稳定环境的隔离测试环境的实践,复用稳定环境,通过流量隔离和数据隔离来生成测试环境。“

以下是详细内容。


环境这个概念,大多数开发者都很熟悉。一个稳定、可预期、低成本的环境也是大家一致的诉求。

如下图所示,我们将环境分为生产环境、测试环境、开发环境3类。很多时候我们会把生产环境、测试环境、开发环境隔离开,就像图上的那个防火墙一样,分为线下环境和线上环境。

image.png

但在实际情况下,考虑公司体量和开发成本等诸多因素,环境的使用和划分会发生一些变化。

例如,基于成本考量,首先要保证的是生产环境,一切以提供服务为核心要务;其次是测试环境,在迁移至线上环境之前我们需要在类似于生产环境的测试环境中进行相应的验证,只有在测试环境中验证无误才可以迁移至生产环境,从而保证系统稳定的过渡。

生产环境

image.png

对于生产环境,准确、稳定的运行是相当重要的,也产生了大量的运维和治理的诉求。

如果测试环境给配置一个节点就够了,生产环境就要考虑备份、主备、分流、容灾等诸多问题,其目的都是为了保障环境的稳定运行。

准确、稳定是生产环境和别的环境的最大区别。这一特点带来了大量的运维的和服务治理的配置诉求,如何有效维护这些配置也是我们基于OAM模型、以IaC的方式来管理配置的初衷,上篇文章中有做分享。

(小编注:云效AppStack正是基于OAM的云原生应用交付平台,企业可以通过应用编排、占位符、变量等声明式定义,实现一套编排多环境差异化部署,同时基于版本和基线实现环境一键拉起、一键回滚。感兴趣的同学点击文末阅读原文可以免费使用)。

生产环境包含了很多种配置,如应用配置、应用镜像、应用运维配置、基础设施运维配置等。这些不同的配置和镜像的内容是由不同的同学关注和管理的。

开发修改代码,代码发布会改变镜像和配置;应用运维会主动修改应用运维配置;基础设施运维会修改基础设施配置。所有的配置改动都会对生产环境产生影响,带来生产环境的变化,进而可能带来风险。

因此生产环境的运维和和管理显然应该是由开发和运维来共同负责的。

测试环境

image.png

测试环境是另一类重要环境。测试环境包含两种类型:一种是集成环境,一种是预发环境。预发环境也就是类生产环境。集成环境主要用于集成测试,或者功能性的验证;预发环境主要在验收的过程中使用。

image.png

测试环境的目标是用尽可能少的资源进行独立的测试,做到隔离、复用、模拟。

例如,应用要跟外部的服务交互,如果外部服务有问题,可以在测试环境中模拟一个。

image.png

以某大数据产品为例,大数据产品大家可能会觉得环境要求太高了,没有办法做测试环境,很多的技术服务如Hive、Kafka、MySQL,对机器的要求会很高:Hive、Kafka需要有很多的机器。另外,还需要Redis做缓存、Zookeeper做服务发现。最早的时候就一套测试环境,这个显然是很低效的。如果有50个开发,共享一套测试环境,频繁冲突的情况下,几乎没有办法做测试。

为了解决这个问题,服务和应用可以做一些分层,这里分成三层。首先是公共的基础服务,比如Hive、Kafka;然后是独立的小服务,比如Redis、Zookeeper。在测试环境下,Redis和Zookeeper全部用单点是没有问题的,可以在一台虚拟机上跑起来;最上层是应用,只部署必须的应用以完成所要的测试工作。

因此,测试环境将会这么管理:首先所有的公共服务是共享的基础服务,所有的测试环境都依赖这些基础服务,各个环境的数据通过逻辑机制(如命名空间)进行隔离。在每一个测试环境会部署一套独立服务的Redis、Zookeeper。

应用层只部署所需要的应用,这样基本可以做到只消耗很小的资源就可以部署一套测试环境。很多的测试资源利用率很低,如果完整的搭一套环境的话你会发现99.99%的情况下,资源利用率都很低。

另外测试环境都应当是临时环境,这一点很重要。如果把测试环境用作长期环境,使用者会习惯某个环境就是他的,例如给环境起名字,这个环境其他人不能用,而这样会造成很大的浪费,毕竟每天使用的时间都是有限的。我们希望测试环境的资源是一个池子,可以被复用,用完即销毁。这也同时要求提高测试效率,在最短的时间内做更多的测试。

开发环境

image.png

开发环境是除了上文我们说到的生产环境和测试环境之外涉及最多的环境,比如开发、构建要用到的一些工具链,都属于开发环境的范畴。在开发环境下,我们的关注点是在本地上怎么把服务顺畅跑起来。

理想的开发环境可以跟其他的服务打通,且双向连通,因此有3个需要解决的问题:首先这个开发环境怎么访问基础环境中的服务,比如另外一个Service。第二个是怎么让其他服务访问到我们开发中的服务。第三个是怎么与其他的开发环境的请求和数据隔离。这也是我们在前面测试环境遇到的类似的问题,因此在开发环境之间也需要类似的手段,云效团队开源的kt-connect就是为了解决这个问题而设计的一个工具。

image.png

在开发环境里也会有相应的一些工具,如上图所示。大家也可以看一下,你常用的有哪些。

测试环境之痛

很多公司、很多人一提到测试环境就会说测试环境不够用、测试环境不稳定。我们在测试环境中会面临哪些挑战?尤其是分布式应用。在微服务化之后,分布式所面对的挑战也越发明显,这些挑战很多和环境有关。

image.png

例如某个应用变化没有做很好的验证,无意间进入到集成环境。这样它进入集成环境的时候本身质量是无法保证的。而在集成测试阶段,应用之间的关系非常复杂,一个服务不稳定,其他的链路都很有可能不稳定。

这也导致我们经常没有办法很好地进行日常集成测试。因为前面的过程没有办法保证,这个时候变化的应用会占用预发环境,而预发环境又是一个相对高成本的环境,不可能经常被某个人占用。于是,为了能让所有人都可以使用预发,对预发的使用将会变成很多人批量进行,这样预发变成长期环境,带来的后果就是预发的时间增长,整个开发周期和交付周期都会增长。在持续交付的流程当中,我们在测试环境当中会面临非常多的挑战:不稳定的问题、资源的问题、集成的问题等。

就目前来说,大家会遇到的比较多的测试环境的问题,大都源自服务没有进行有效的治理。服务方法多,耦合高,一旦某个服务出现问题,其他的都会受到影响。当一个环境的服务都是处在变化中时,由于随时都有不稳定的服务在部署,整个环境也将是不稳定的。

集成环境无法稳定的后果是大量的测试迁往预发,预发成为瓶颈之后又往线上迁移。任何应用最终都会用线上环境来兜底。

总结来看,测试环境主要面临如下2个挑战:

第一个是如何解决服务之间的依赖。比如A对C的强依赖,A的功能成功与否取决于C,而且C变化之后也要在A上面做相应的验证,保证C的变化是对的。

image.png

另外一个是环境本身的,主要有2点,一个是机器的稳定性,另一个是服务本身的稳定性

image.png

机器的稳定主要是:有效应对硬盘故障,网络故障等情况,做好系统的备份和容灾。

服务本身的稳定主要是:有效确保每个服务自身的可用性,因为假如一个应用的可用性是90%的话,那10个应用就是90%的10次方,导致整个的系统都会很低。

如何保证测试环境的稳定性

image.png

上文我们说到了测试环境存在的两种挑战。任何测试环境都需要保证其稳定性,降低使用线上环境的风险。那么如何保证测试环境的稳定性呢?

在测试环境中常用的实践主要有:双机部署、N+1部署、隔离环境等

image.png

例如我们一个应用至少部署两个Pod,保证至少一个在提供服务,不能让两个同时重启。确实会发生这样的情况:在某个测试环境,如果某个服务只有一个副本,该服务发生部署导致重启,会导致整个测试的不可用。在这种情况下双机部署是很好的快速解决手段,但也占用了较多的资源。

image.png

为了解决双机部署资源占用高的缺点,N+1的部署方式应运而生。采用滚动的方式逐个替换服务应用。这样你的机器就只有一个是处于变化当中,其他都是work的。这也是K8S默认的方式,一般会生成新的实例,然后再把旧的实例下掉。

image.png

为了保证测试系统的稳定性,我们需要做隔离,尽量做到除自己修改的应用,其它应用都是稳定的。

在阿里,团队引入了项目预集成环境,在阿里内部叫项目环境,这是一个隔离出来的环境,针对某一个特性在开发的阶段单独的拉取一个环境出来。

综上所述,预集成环境是隔离的,跟谁都没有关系,所依赖的其它服务都来源于稳定的环境,以保证依赖的服务都是稳定的,以便进行独立的开发和测试。

在项目早期的时候,项目预集成环境里依赖的环境还是日常集成环境,无论如何肯定比什么都不做直接放入日常集成环境里面好很多。这个时候我们发现日常集成环境还是有问题,因为在项目初期并不能保证所有的提交都会在项目预集成环境去做验证,因此会导致日常集成环境里面的依赖也可能存在很大的问题,其实本质上又回到了我们要治理日常的集成环境的事情,怎么样维持相对稳定。

image.png

针对上述问题,我们引入稳定环境的概念。既然我们将环境隔离出来了,但隔离依赖的基础环境不稳定,这个时候假如我们有一个稳定的环境是否就能解决问题了呢?

什么样的环境是稳定环境呢?就是能够发布到线上版本的环境,线上环境肯定是稳定环境,所以我们的稳定环境其实是由与线上版本一致的应用服务组成的,跟线上的服务是一致的。线上稳定,这个环境就是稳定的,所以我们就可以在这种稳定环境下再去创造隔离环境,从而保证整体稳定性。

当有了稳定的基础环境,在应用部署到生产环境之后,也同样要把它部署到基础环境中去,提供一个给测试环境作为依赖的基础环境。有了这样一个基础环境依赖,在我们应用开发时,拉出来的环境就是完全隔离的,只包含和我紧密相关的几个变化当中的应用,其余所有的依赖的服务都是从基础环境里面来的。

这里提到了基础环境的概念,那么什么是基础环境呢?基础环境是一个稳定的环境,当有了一个稳定的集成环境就可以做隔离的环境,特性测试将可以基于该隔离环境,依赖的流量也可以在隔离环境里面找。但基础环境有一定的维护成本,虽然部署成本相对来说很低,其占用的机器资源相对于一般大公司来说不是太大的问题,但对小公司可能是一个问题。但主要的成本是基础环境的维护,对基础环境进行监控并修复出现的问题,这在人力上需要一定的投入。

基础环境的维护者一般不是这个环境的使用者,所以这个时候需要有一个比较成熟的机制保证基础环境长期稳定的运行。我们开一下脑洞,如果说没有新的基础环境,哪一个环境是最稳定的呢?我们在前面把线上线下用防火墙隔开了,为什么隔开大家都知道,我们是怕安全风险,怕数据污染,但是如果我们的隔离能力做的足够好,服务路由做的足够好,监控做的足够好,安全保护做的足够好,我们是可以用生产环境来做基础环境的。

生产环境做基础环境,要解决两个重要的问题,第一个是流量隔离,流量隔离相对来说问题不太大,从以前面向资源到现在面向流量的隔离有很多现成的手段可以做。第二个是数据隔离。这个是挺大的挑战,数据形式有很多种,比如说消息队列和普通的数据库不一样,数仓又不一样,很多麻烦的问题在这里,但是具体到某一个点上都有办法解决。

小结

总结一下,对于生产环境,准确、稳定最重要,我们推荐以应用为中心的基于OAM和IaC的实践方式;对于测试环境,隔离、低成本和稳定的依赖是最重要的,我们推荐基于稳定环境的隔离测试环境的实践,复用稳定环境,通过流量隔离和数据隔离来生成测试环境。通过环境建设,我们解决了研发过程中的资源冲突,下一章我们将关注研发过程中的协作问题。

image.png

点击下方链接体验云效云原生应用交付平台AppStack!

https://www.aliyun.com/product/yunxiao/appstack?channel=yy_rccb_36

lQLPDhshq7rXr9DNBDjNB4Cw6h-soueBRw4CB9bnfwCoAA_1920_1080.png

相关文章
|
3月前
|
缓存 运维 数据库
【测试人员兼职指南】利用专业技能:如何从测试转向开发赚钱
本文分享了作者作为测试人员如何利用专业技能转向开发来兼职赚钱的经验,包括分析和解决登录页面跳转、避免重复账号注册、用户登录后首页显示用户名以及添加退出功能等问题,并提供了Django项目中使用sqlite3数据库和后台管理的扩展技巧。
125 1
【测试人员兼职指南】利用专业技能:如何从测试转向开发赚钱
|
3月前
|
Java 测试技术 开发者
在软件开发中,测试至关重要,尤以单元测试和集成测试为然
在软件开发中,测试至关重要,尤以单元测试和集成测试为然。单元测试聚焦于Java中的类或方法等最小单元,确保其独立功能正确无误,及早发现问题。集成测试则着眼于模块间的交互,验证整体协作效能。为实现高效测试,需编写可测性强的代码,并选用JUnit等合适框架。同时,合理规划测试场景与利用Spring等工具也必不可少。遵循最佳实践,可提升测试质量,保障Java应用稳健前行。
48 1
|
1月前
|
测试技术 网络安全
什么是软件测试? 软件测试都有什么岗位 ?软件测试和调试的区别? 软件测试和开发的区别? 一位优秀的测试人员应该具备哪些素质? 软件测试等相关概念入门篇
文章全面介绍了软件测试的基本概念、目的、岗位分类、与开发和调试的区别,并阐述了成为优秀测试人员应具备的素质和技能。
144 1
什么是软件测试? 软件测试都有什么岗位 ?软件测试和调试的区别? 软件测试和开发的区别? 一位优秀的测试人员应该具备哪些素质? 软件测试等相关概念入门篇
|
21天前
|
人工智能 监控 测试技术
云应用开发平台测试
云应用开发平台测试
37 2
|
1月前
|
敏捷开发 测试技术
开发模型(瀑布、螺旋、scrum) 和 测试模型(V、W)、增量和迭代、敏捷(思想)及敏捷开发 scrum
文章详细介绍了软件开发过程中的不同开发模型(瀑布、螺旋、Scrum)和测试模型(V模型、W模型),以及增量和迭代的概念,最后阐述了敏捷思想及其在敏捷开发(如Scrum)中的应用。
54 0
开发模型(瀑布、螺旋、scrum) 和 测试模型(V、W)、增量和迭代、敏捷(思想)及敏捷开发 scrum
|
2月前
|
测试技术 持续交付 UED
软件测试的艺术与科学:平衡创新与质量的探索在软件开发的波澜壮阔中,软件测试如同灯塔,指引着产品质量的方向。本文旨在深入探讨软件测试的核心价值,通过分析其在现代软件工程中的应用,揭示其背后的艺术性与科学性,并探讨如何在追求技术创新的同时确保产品的高质量标准。
软件测试不仅仅是技术活动,它融合了创造力和方法论,是软件开发过程中不可或缺的一环。本文首先概述了软件测试的重要性及其在项目生命周期中的角色,随后详细讨论了测试用例设计的创新方法、自动化测试的策略与挑战,以及如何通过持续集成/持续部署(CI/CD)流程优化产品质量。最后,文章强调了团队间沟通在确保测试有效性中的关键作用,并通过案例分析展示了这些原则在实践中的应用。
70 1
|
2月前
|
测试技术 UED 开发者
软件测试的艺术:从代码审查到用户反馈的全景探索在软件开发的宇宙中,测试是那颗确保星系正常运转的暗物质。它或许不总是站在聚光灯下,但无疑是支撑整个系统稳定性与可靠性的基石。《软件测试的艺术:从代码审查到用户反馈的全景探索》一文,旨在揭开软件测试这一神秘面纱,通过深入浅出的方式,引领读者穿梭于测试的各个环节,从细微处着眼,至宏观视角俯瞰,全方位解析如何打造无懈可击的软件产品。
本文以“软件测试的艺术”为核心,创新性地将技术深度与通俗易懂的语言风格相结合,绘制了一幅从代码审查到用户反馈全过程的测试蓝图。不同于常规摘要的枯燥概述,这里更像是一段旅程的预告片,承诺带领读者经历一场从微观世界到宏观视野的探索之旅,揭示每一个测试环节背后的哲学与实践智慧,让即便是非专业人士也能领略到软件测试的魅力所在,并从中获取实用的启示。
|
3月前
|
测试技术 API
软件测试:Postman 工具的使用。开发及测试均需要掌握的测试工具
这篇文章详细介绍了Postman工具的各个模块功能,包括创建请求、集合、环境、自动化测试等,并解释了如何使用Postman进行GET、POST、PUT和DELETE等常见HTTP请求的测试。
|
3月前
|
运维 Kubernetes 监控
|
3月前
|
机器学习/深度学习 人工智能
高于临床测试3倍准确率!剑桥大学开发AI模型,提前6年预测阿尔茨海默症
【8月更文挑战第9天】剑桥大学研发的人工智能模型在预测阿尔茨海默症方面取得突破,准确率比传统临床测试高三倍,能提前六年预测疾病发生。该模型基于深度学习,利用大量临床及神经影像数据识别生物标志物,预测准确性达80%。这一成果有望促进早期干预,改善患者预后,但仍需更大规模研究验证,并解决隐私与公平性等问题。论文已发表于《The Lancet》子刊。
51 6
下一篇
无影云桌面