[关闭]
@gaoxiaoyunwei2017 2018-01-02T09:48:57.000000Z 字数 7476 阅读 429

阿里测试环境运维及研发效率提升之道 --- 刘湘疆·阿里

北哥


讲师简介

WX20180102-171652.png-74.2kB

刘湘疆(青冥),阿里巴巴运维中台技术专家,2010年加入阿里巴巴,先后从事配置管理、工程效能等相关工作,目前负责阿里巴巴集团测试环境运维及研发效率提升。对于测试环境效率、自动化部署、持续交付有较深刻的认识和实践经验。

我是刘湘疆,来自阿里巴巴研发效能事业部,前几年一直负责集团测试环境的管理和运维。今天在这里跟大家分享一下阿里巴巴在测试环境方面运维和研发效率提升的一些经验和实践。

大家平时可能关注生产环境的比较多,各种分享活动绝大多数也是基于生产环境的,而今天我要讲的是测试环境。生产环境最关注的就是稳定,测试环境来说更关注的是研发效率,如何从一行代码最快的保证质量发到线上去,这个是我们测试环境最关注的。

测试环境特点如下:

image.png-112.7kB

资源配置低 :测试环境一般来说资源配置都比较低,跟线上不太一样,至少在阿里是这样的。大到网络、机房包括服务器配置都比线上的配置要差,小到虚拟机、容器,虚拟化都比线上要高。这是不太一样的地方,这些对于我们来说也是一些挑战,后面会讲到。

部署频繁 :测试环境下的部署是非常非常频繁的。比如说你开发一个功能,可能线下部署10到20次,线上才发布1次。部署这块对于研发来说是非常关注的,就是怎样能快速看到我部署之后的效果。

业务测试干扰 :这块也是很明显,因为当你业务需求越来越多的时候,并行的开发就会很多,而且线下环境类型比较多,比如开发环境、性能环境,各式各样的环境,这些环境之间会有一些干扰。以下两种情况比较常见,第一种是我要调用你的服务,结果你的服务器挂了。第二种是可能多个环境都在提供某个服务,当你要请求这个服务的时候,就可能会调错了。这些情况都会干扰到我们的测试。

今天的分享主要从资源稳定性部署效率,以及业务稳定性这三个方面来讲。
image.png-60.8kB

一. 资源稳定性

image.png-175kB

刚才我们提到,测试环境的配置都比较差,绝大多数的机器都是线上淘汰的过保的物理机充当的,虽然过保了实际上还是能用的,为了节省成本基本上都是当测试机来用。这些机器的故障率肯定比线上的要高很多的,那我们要怎么来保证稳定性呢?就是在容器交付和容器运行两个阶段怎么尽量保证能够稳定。

image.png-344.1kB

容器交付我们主要是做了资源池的调度策略。右侧这边图是一个简化版的容器生产的链路,资源池上面是一层调度,分为资源管理和资源生产,当然,这里还有很多其他的模块,我这里就不细化了,重点是突出中间那块。最上面有很多的上层系统来调用申请机器,我们线上环境没有资源池动态分配这层的,就是直接上层系统和一层调度做这些事情,因为下层本身是比较稳定的。

对于测试环境来说,我们在中间插了一层,就是资源池的动态分配,这个系统有五个模块,分别是宿主机评分,应用环境分级,资源池管理,(就是对资源池怎么进行合理的调度和分配,这个后面会详细讲到),容量预测,最后一个是分配器。

image.png-355.2kB

下面详细说下资源池动态分配系统的模块。

image.png-255.4kB
即使我们做到了上面的资源交付,宿主机还是会有问题的,这个是难以避免的。大多数的做法是自愈,当我发现有问题的时候,怎么样做到自愈,让用户没有感知。我们没有办法避免某个机器不出问题,但是我们可以尽量避免用户感知到。

我们这里有一个自愈系统,看右边这张图,有四个重要的模型:条件模型、原子服务模型、条件处理模型、自愈事件模型。下面结合场景进行说明。

image.png-235.3kB

上层系统可以对接很多了,比如刚刚说到的发布系统,还有监控系统,发现磁盘满了清理磁盘,发现应用问题自动把服务拉起来,还有调度系统,刚才提到的底层负责资源管理的调度系统,当它发现某台物理机已经出问题的时候,可以把上面现有的容器迁移走,把这个物理机下线或送修,这些都是可以对接多个上层系统的。总的来说,非业务系统问题相对还是比较好处理的。

而对于业务性的问题处理相对麻烦点,因为业务具有多样性。比如健康检查,发现有问题就需要对应用进行重启,甚至做容器迁移。这个我们尝试在做,从经验上来看,对应用上来说是有一些要求的:

以上都是经验,大家可以参考一下。

二. 部署效率

image.png-162kB

对于研发同学来说,大家最关注的就是研发效率,写完代码之后,希望能立刻看到效果,并且迅速得到验证。这里面我们认为比较耗时的三个部分就是构建、部署和测试,今天主要是对部署和测试这块会重点讲一下。

接下来重点讲讲部署这块,我们认为主要就是能做到快速部署、快速回滚,后面会详细讲。

对于测试来说,一个是自动化测试,这样的话你才能在整个pipeline里跑的起来;还有一个是业务的稳定性,测试环境的业务稳定性相信是困扰很多开发测试同学的大问题。其实自动化测试跟业务稳定性这两个东西是相辅相成的,环境越稳定,自动化才能越跑越成熟。反过来说,自动化越成熟,能够为环境的稳定性提供越大的自动化监测保障。

image.png-362.9kB

部署效率我们主要是从部署策略介入的。业界用的比较多的策略一般是分批部署,这也是最常见的一种方式。比如说现在有两台机器,如右边这张图,黄色三角表示流量,这两个都有流量进入。开始部署的时候先部署第一台,这时只有第二台在提供服务,等第一台部署好了之后,流量全部打到第一台来了,第二台再部署,最终达到两台都部署完成,流量均衡,这就是分批部署。

在整个部署过程中,总有一台机器提供服务,保证服务不间断。从部署时间和回滚时间上来看,分几批部署,部署总时长就是单台的时间乘以批次。从整个部署时间上来看,单台部署时间越长,那么部署时间就会拉的很长,所以会尽量减少批次,又要考虑到剩余的机器能不能撑得住线上的流量。比如说回滚的时候就是这样,部署到倒数第二批的时候发现有问题,换个时候不能把所有部署过的批次一下子回滚掉,因为线上剩余的那一批可能撑不住所有的流量,这个时候你分几批发,就得分几批回滚。所以回滚总时长这里最好的情况就是在第一批就发现了问题,回滚的时间就等于单台部署的时间。这是线上普遍采用的做法,我们原来在测试环境也是这么做的。

image.png-280.1kB
后来我们在想,测试环境有没有办法优化一下,我们考虑用蓝绿部署。这里简单讲一下,还是两台机器,只有一台在提供服务,我们称之为主机,另外一台没有提供服务,我们称之为备机,上面是什么版本我也不关心。部署开始的时候,先部署备机,部署完之后把流量切到备机来,这时备机这时就变成新的主机了,原来的主机变成备机了。需要回滚的时候,直接把流量切过来就好了。

这种做法部署时间是最短的,只需要单台的时间就够了,因为另外一台不需要部署。回滚时间其实取决于你切流的时间,我们可以做到在几秒钟之内就切好。

蓝绿部署是用空间来换取时间,我们用新的一批机器来来部署,部署完了之后替换之前的那批机器。对阿里来说,在线上这样做的话,是不太可取的,因为线上的量实在是太大了,一个应用就上千台服务器,要采用蓝绿部署的话,需要再拿出一千台服务器来先部署然后再下掉,而且我们的应用发布是频率很高的,这对于资源的消耗是非常大,不太可能采取这种方式。但是对线下来说我们测试环境两台机器就够了,当初在分批部署的时候,采用两台机器,并不是说我们线下流量有多大,必须要两台才能撑得住。测试环境流量其实很小,一台服务器就够了,之所以用两台是为了保证稳定性。在部署的时候,原来采用分批发布的时候,至少还有一台总是在提供服务的。

我们采用这种方式主要是为了降低部署时间,我们现在正在尝试用这种方式来做。

image.png-211.6kB

除了在上节说到的构建策略外,还进行了以下优化。

三. 业务稳定性

image.png-252.1kB

第一,业务方希望我们的环境要足够稳定,所调用的服务要一直正常运行,随时调用都可以,而且是稳定的,最新的,无干扰的。第二,调用的时候不希望调到干扰服务器上去,包括消息也是一样的,不希望应该发给我的消息,被别人抢掉了。第三,高效,比如说建立一个隔离环境的时候,不希望做一大堆的配置来实现。那么怎么样做到这几点呢:这里我讲两点,一个是基础环境,其次是逻辑隔离。

image.png-323.4kB

现在比较典型的研发流程是这样的,从开发测试到集成测试,到预发测试,再到上线。在每个研发阶段都有对应的环境做支撑。这里需要注意下开发环境,开发环境之间互相调用的话,肯定会有干扰,并且不稳定。所以发布上线完之后我们会去部署一个基础环境,开发环境去调用稳定环境的服务。基础环境部署的是主干代码,也就是线上的代码,会自动部署。

这里面的隔离是怎么做到的呢?比如,怎么让开发环境调到基础不调到开发呢?甚至还有很多其他的开发环境,为什么可以做到不调用呢?

image.png-245.7kB
重点是逻辑隔离。现在阿里的业务非常多,并行需求特别多,一个应用有可能甚至同时会有几十个开发环境存在,当调用服务的时候,很有可能会出现调用错乱。我们是通过隔离组来解决这个问题,原理是根据源头的IP所在隔离组进行路由。

看上面的图所示,隔离组里面有三个应用,基础环境里有所有的应用,当我发现隔离组里面没有这个应用服务的时候,就会调基础环境,基础环境调完之后还能调回到你的隔离组环境里去。不管怎样每一次都会先检查隔离组里有没有我要调用的服务。在搭建隔离环境做测试的时候,只需要搭建你要修改的那几个应用就可以了,最大限度的去复用基础环境下的服务。

image.png-337.1kB
上面是没有逻辑隔离的情况,上面每个圈代表一个环境,ABCDE代表不同的应用,当A1在调用的时候只要发现有B的服务都会调用到,随机调用的,可能这次是B1下次是B2,乱糟糟的。

image.png-320kB
这张图里创建了两个隔离组。在隔离组1里,没有B的环境,所以A1会去调用B的基础环境;再看隔离组2,这个隔离组里面有B的环境,所以A2就调B2,没有C了再往基础环境调。这个就是跟没做隔离的区别,上一个图每个圈上面至少两三个线,而这个只会调一个。

当然这里面还有一个问题,比如说在隔离组2里,B1的服务挂掉了,这时A2是不应该调用基础环境B的,否则会掩盖B1挂掉的事实,这个时候隔离逻辑还是会尝试去调用B1,并报错说调用不到。

image.png-315kB
这个是最终效果图。大家都在隔离组里,没有散的机器。与上一张图的另一个区别是这条红线,这是一个比较特殊的隔离逻辑的高级用法。

比如A是一个前端应用,B是后端的服务,A调用B的服务,如果我是一个B的开发,通过前端页面方式测试B服务的时候,一般需要再搭一个A的测试环境,这种情况好处理,只要搭一个即可。如果是多个呢?比如像物流发货这种情况,你需要先要购买,然后付款,整个走完之后才能发货,可能需要把整个交易链路都搭一遍,这时你会发现这个链路很长,要搭建的环境很多,对机器资源也是一种浪费,根本没有必要。有没有更高效的方式呢?这里面实现了一个逻辑,就是通过用户的请求来精准路由。比如你是从某个隔离组发起测试,只有你访问的时候会走那条路,而其它人还是走这条路,这个与蓝绿部署里面的备机有点像,备机在下线之后,只是被隔离了,机器并不会被释放掉,一方面这个机器可以用来给开发做debug用,另一方面有问题回滚比较快。
怎样保证还在提供这个服务,但是这个服务又不被别人调用到呢?我们把这个服务单独放在一个隔离组里,就不会被任何人调用到,只是被隔离起来了而已,实际上服务都还在。要切换的时候,只要重新拉回来就行,秒级生效。

讲一下实现的原理,阿里有一个中间件叫做鹰眼,可以查看调用链路。下每个请求会生成一个ID,这个ID会随着每一次调用一个一个传下去,所以当你把这个ID都统计出来,就能知道这条链路是什么样子的。我们也是利用了这个东西,把源头的请求IP放在ID里面,每次路由的时候都会看ID有没有跟某个隔离组进行关联。我们有一个web操作界面,想与哪个隔离组关联,界面上点一下就好。当你服务调用的时候,服务路由会把ID取出来,看看你的IP有没有做关联,如果有的话就到那个隔离组里面去调用。
它的好处就是快速的搭建一整套隔离环境,只要在上面点几下,要哪几个应用一下子就好了,自然而然就呈现一个封闭的隔离组。
这个东西因为是涉及到阿里的中间件产品,所以大家可能不能直接拿去用,但是这里提供一个思路,这套东西目前来看已经能够满足很多场景了。

如果在没有使用鹰眼产品的情况下可以采用这种方式,回过头来看看上一张图。有一个简单点的方法就是直接看标,每台机器打了标之后,这个是隔离组标,这个是基础环境标,比如第一个圈,发现自己的标是隔离组的,调服务的时候,发现这个组里面没有需要的服务,就调基础的了,基础再往下看的时候,就看他自己的标。这会存在一个问题,就是一旦调出来就调不回去了,所以要保证所有你要测的东西都在这个里面。遇到问题排查也比较简单。

以上就是在业务稳定性这块做的一个逻辑隔离。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注