乐趣区

关于阿里云:开发之痛稳定的测试环境怎么就那么难-研发效能提升36计

专栏策动|雅纯

意愿编辑|jimmy、吕瑞星

“对于生产环境,精确、稳固最重要,咱们举荐以利用为核心的基于 OAM 和 IaC 的实际形式。

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

以下是具体内容。


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

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

但在理论状况下,思考公司体量和开发成本等诸多因素,环境的应用和划分会产生一些变动。

例如,基于老本考量,首先要保障的是生产环境,所有以提供服务为外围要务;其次是测试环境,在迁徙至线上环境之前咱们须要在相似于生产环境的测试环境中进行相应的验证,只有在测试环境中验证无误才能够迁徙至生产环境,从而保证系统稳固的过渡。

生产环境

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

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

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

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

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

开发批改代码,代码发布会扭转镜像和配置;利用运维会被动批改利用运维配置;基础设施运维会批改基础设施配置。所有的配置改变都会对生产环境产生影响,带来生产环境的变动,进而可能带来危险。

因而生产环境的运维和和治理显然应该是由开发和运维来独特负责的。

测试环境

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

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

例如,利用要跟内部的服务交互,如果内部服务有问题,能够在测试环境中模仿一个。

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

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

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

应用层只部署所须要的利用,这样根本能够做到只耗费很小的资源就能够部署一套测试环境。很多的测试资源利用率很低,如果残缺的搭一套环境的话你会发现 99.99% 的状况下,资源利用率都很低。

另外测试环境都该当是长期环境,这一点很重要。如果把测试环境用作长期环境,使用者会习惯某个环境就是他的,例如给环境起名字,这个环境其他人不能用,而这样会造成很大的节约,毕竟每天应用的工夫都是无限的。咱们心愿测试环境的资源是一个池子,能够被复用,用完即销毁。这也同时要求进步测试效率,在最短的工夫内做更多的测试。

开发环境

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

现实的开发环境能够跟其余的服务买通,且双向连通,因而有 3 个须要解决的问题:首先这个开发环境怎么拜访根底环境中的服务,比方另外一个 Service。第二个是怎么让其余服务拜访到咱们开发中的服务。第三个是怎么与其余的开发环境的申请和数据隔离。这也是咱们在后面测试环境遇到的相似的问题,因而在开发环境之间也须要相似的伎俩,云效团队开源的 kt-connect 就是为了解决这个问题而设计的一个工具。

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

测试环境之痛

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

例如某个利用变动没有做很好的验证,无意间进入到集成环境。这样它进入集成环境的时候自身品质是无奈保障的。而在集成测试阶段,利用之间的关系非常复杂,一个服务不稳固,其余的链路都很有可能不稳固。

这也导致咱们常常没有方法很好地进行日常集成测试。因为后面的过程没有方法保障,这个时候变动的利用会占用预发环境,而预发环境又是一个绝对高老本的环境,不可能常常被某个人占用。于是,为了能让所有人都能够应用预发,对预发的应用将会变成很多人批量进行,这样预发变成长期环境,带来的结果就是预发的工夫增长,整个开发周期和交付周期都会增长。在继续交付的流程当中,咱们在测试环境当中会面临十分多的挑战:不稳固的问题、资源的问题、集成的问题等。

就目前来说,大家会遇到的比拟多的测试环境的问题,大都源自服务没有进行无效的治理。服务办法多,耦合高,一旦某个服务呈现问题,其余的都会受到影响。当一个环境的服务都是处在变动中时,因为随时都有不稳固的服务在部署,整个环境也将是不稳固的。

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

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

第一个是 如何解决服务之间的依赖。比方 A 对 C 的强依赖,A 的性能胜利与否取决于 C,而且 C 变动之后也要在 A 下面做相应的验证,保障 C 的变动是对的。

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

机器的稳固次要是:有效应对硬盘故障,网络故障等状况,做好零碎的备份和容灾。

服务自身的稳固次要是:无效确保每个服务本身的可用性,因为如果一个利用的可用性是 90% 的话,那 10 个利用就是 90% 的 10 次方,导致整个的零碎都会很低。

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

上文咱们说到了测试环境存在的两种挑战。任何测试环境都须要保障其稳定性,升高应用线上环境的危险。那么如何保障测试环境的稳定性呢?

在测试环境中罕用的实际次要有:双机部署、N+ 1 部署、隔离环境等

例如咱们一个利用至多部署两个 Pod,保障至多一个在提供服务,不能让两个同时重启。的确会产生这样的状况:在某个测试环境,如果某个服务只有一个正本,该服务产生部署导致重启,会导致整个测试的不可用。在这种状况下双机部署是很好的疾速解决伎俩,但也占用了较多的资源。

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

为了保障测试零碎的稳定性,咱们须要做隔离,尽量做到除本人批改的利用,其它利用都是稳固的。

在阿里,团队引入了我的项目预集成环境,在阿里外部叫我的项目环境,这是一个隔离进去的环境,针对某一个个性在开发的阶段独自的拉取一个环境进去。

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

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

针对上述问题,咱们引入稳固环境的概念。既然咱们将环境隔离进去了,但隔离依赖的根底环境不稳固,这个时候如果咱们有一个稳固的环境是否就能解决问题了呢?

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

当有了稳固的根底环境,在利用部署到生产环境之后,也同样要把它部署到根底环境中去,提供一个给测试环境作为依赖的根底环境。有了这样一个根底环境依赖,在咱们利用开发时,拉进去的环境就是齐全隔离的,只蕴含和我严密相干的几个变动当中的利用,其余所有的依赖的服务都是从根底环境外面来的。

这里提到了根底环境的概念,那么什么是根底环境呢?根底环境是一个稳固的环境,当有了一个稳固的集成环境就能够做隔离的环境,个性测试将能够基于该隔离环境,依赖的流量也能够在隔离环境外面找。但根底环境有肯定的保护老本,尽管部署老本相对来说很低,其占用的机器资源绝对于个别大公司来说不是太大的问题,但对小公司可能是一个问题。但次要的老本是根底环境的保护,对根底环境进行监控并修复呈现的问题,这在人力上须要肯定的投入。

根底环境的维护者个别不是这个环境的使用者,所以这个时候须要有一个比拟成熟的机制保障根底环境长期稳固的运行。咱们开一下脑洞,如果说没有新的根底环境,哪一个环境是最稳固的呢?咱们在后面把线上线下用防火墙隔开了,为什么隔开大家都晓得,咱们是怕平安危险,怕数据净化,然而如果咱们的隔离能力做的足够好,服务路由做的足够好,监控做的足够好,平安爱护做的足够好,咱们是能够用生产环境来做根底环境的。

生产环境做根底环境,要解决两个重要的问题,第一个是流量隔离,流量隔离相对来说问题不太大,从以前面向资源到当初面向流量的隔离有很多现成的伎俩能够做。第二个是数据隔离。这个是挺大的挑战,数据模式有很多种,比如说音讯队列和一般的数据库不一样,数仓又不一样,很多麻烦的问题在这里,然而具体到某一个点上都有方法解决。

小结

总结一下,对于 生产环境 ,精确、稳固最重要,咱们举荐以利用为核心的基于 OAM 和 IaC 的实际形式;对于测试环境,隔离、低成本和稳固的依赖是最重要的, 咱们举荐基于稳固环境的隔离测试环境的实际,复用稳固环境,通过流量隔离和数据隔离来生成测试环境。 通过环境建设,咱们解决了研发过程中的资源抵触,下一章咱们将关注研发过程中的合作问题。

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

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

退出移动版