去哪儿网Noah环境构建平台的演进

背景

随着业务日益复杂,应用微服务化已成为主流趋势,业务领域通常在多个微服务应用中实现。DevOps 工程从应用角度,虽实现了应用流水线和项目流水线,但也面临着测试阶段管理多套应用流水线的复杂场景。通常情况下,这些业务会存在多套互相隔离的环境,而这些环境的构建也依赖人工处理资源申请和部署。由于构建不易,这些环境通常被长期反复使用,并需要定期与生产环境同步以确保开发和测试的有效准确。这些工作要求工程师对业务的应用架构熟悉且有时间频繁进行操作,但实际上这些工作大多落在项目资深的 DEV 或 QA 身上,浪费了宝贵的人力资源。

因此,我们可以考虑建立"环境构建平台",实现环境即用即建,让 DEV 和 QA 专注于自己擅长的事情,并最终节约人力资源提升效率。Qunar 的基础平台团队对此问题进行了长期实践,本文将分享 Qunar 在测试环境治理领域的实践经验和思考。

Noah 环境平台自 2019 年初起,已经迭代到 3.0 版本,目前 Noah 环境平台承接了全司各业务的开发与联调环境近 2000 套,覆盖几乎全部业务线,每日构建百余次,保持了 80% 以上的构建成功率。

其演进大致分为三阶段,即 2020 年前的自动构建阶段,2020 之后的降本增效阶段,与 2022 年开始的稳定性治理。"自动构建"阶段着重解决测试环境构建过程中涉及的多任务编排与多系统调用;"降本增效"在此基础上追求更低的人工运维成本和资源占用成本,同时提升环境构建效率和质量。"稳定性治理"则进一步优化运维成本与开发效率,力求做到无感知的测试环境。

1.第一阶段:定义并自动构建环境

我们总会听到 DEV 抱怨项目 delay 是因为"测试环境不好用",同时,QA 也在抱怨为测试环境投入了太多精力,分散了对测试本身的投入。在这些场景中"测试环境"自身概念并不明确。DEV 视角下的测试环境通常指下图中的"环境 A",其聚焦在自身业务的测试环境。在 QA 视角下,测试环境可能还包括不同业务的 A、B 环境联调。在中间件团队视角下,DEV 和 QA 的所谓测试环境可能只是其搭建的另一套非生产环境服务集群。这些环境中,业务环境部分是平台需要解决的重点。

整体解决思路是:

1、通过对环境下定义,实现环境配置化。

2、通过拆分环境与资源的构建流程、阶段,针对性实现其状态机。

3、根据环境与资源的定义和状态对比,获取其差异,并据此动态编排构建任务。

4、调度执行构建任务的有向无环图,完成构建。下面重点介绍落地过程中的几个关键点。

1.1 关键点1: 如何标准化定义环境

在去哪儿网,使用 git 管理后端应用工程的项目开发时,通常使用分支开发主干发布模式。其默认 master 分支为主分支,各项目开发时创建新 dev 分支,并在上线后合并分支 commit 到 master 分支。其他 dev 分支此时需要合并最新的 master 分支 commit,才可以继续发布。同样,所有的开发与测试环境都应以生产环境为准。此时,生产环境的"应用服务"与"数据库"等资源的配置与依赖信息就是创建其他环境的参考,即标准化环境定义,即"模版"。

下图为 Noah 平台环境详情页对这些资源进行的分类。将下述信息作为模版,即实现了业务的应用层配置标准化和持久化,解决了测试环境是什么问题。

1.2 关键点2: 将硬编码的环境配置变量化

在对环境进行定义的过程中,我们发现有部分配置信息是与当前环境相关的,比如数据库地址。当存在多套环境时,工程代码中会使用多套配置文件,硬编码实现,依赖 maven 参数切换 profile。如支持环境自动构建后,依然使用此方式,必然导致配置文件数量上涨(无论是人工修改还是自动修改)。此时,将配置文件中的差异部分再次定义为变量,即可实现一套配置通用。

工程代码中的配置文件

修改后的配置文件还不能直接使用。这些${变量}需要在服务启动前被替换为当前环境的真实值,才是一份可用的环境配置文件。借助应用发布平台的自定义脚本机制,在启动服务阶段,变量替换脚本 replacer 负责实时查询此应用所属环境的变量信息,缓存到本地,同时扫描当前应用部署目录的本地文件,完成匹配与替换。

此外,在去哪儿网大多数应用还会使用远程配置中心进行配置文件管理。这部分文件会在应用启动时被 SDK 拉取到本地缓存。借助上述步骤中 repalcer 在本地缓存的变量文件,SDK 同样也可实现替换从配置中心拉取到本地的配置文件。

上述方式在使用虚拟机时有效,在随后的容器化场景下,因替换发生在部署阶段,只需应用部署平台的工作流稍作适配即可。

1.3 关键点3: 基础设施即代码

环境构建平台作为 devops 的上层应用,自身需要借助相关工具系统才能实现构建功能。此时,需要这些服务提供以下能力。在此过程中,我们发现部分功能(主要是数据库构建、虚拟机管理)存在短板,不满足构建需求。因此进行了补齐开发。

1.4 关键点4: 编排与执行构建工作流

上述关键问题解决后,理论上环境就可以进行构建了。此时的 Noah 着重解决一键构建环境,因而其构建任务包括从准备虚拟机、发布应用、到注册域名等操作。在实际操作中,需要在保留任务依赖情况下,尽可能提升执行效率。

Noah 将环境的构建定义为 4 个阶段。在"锁定资源"时,完成虚拟机与数据库资源的申请;在"交付"时,利用 saltstack 完成虚拟机定制,同时发布应用;在"网络构建"阶段完成域名的创建;最后,预留环境验证扩展。

下图展示了应用类型资源的构建任务执行日志。

此关键点是自动化构建环境的核心,其有两个难点必须解决:有效率的任务编排调度执行、环境资源状态维护。

环境构建任务编排后是一个有向无环图(DAG)。任务间存在依赖,既有可并行的任务,也有必须串行的任务。比较典型的是"同一资源构建任务串行,不同资源构建任务并行"。同时,利用前面对构建过程的分阶段定义,此处先进行"中间件"与"数据库"类型资源构建,待其结束后,再进行"应用"的构建,可以兼顾构建效率与依赖。当然,进一步细化,可以将"应用"的虚拟机定制任务也并行执行,进一步提升构建效率。

DAG 任务图的调度执行并不复杂,但是要注意高并发下的事务控制与效率。此处,Noah 最初使用任务图粒度的分布式锁与 MySQL 事务方案,其能撑起 2019 年的使用量,但稳定性欠佳。2021 年后,通过 redis 缓存部分必要的运行时数据,配合 MySQL 存储冷数据,进一步提升了调度的稳定性和吞吐。

至于"环境资源状态维护"则需要存储当前环境的所有资源的所有定义与运行时信息,并结合状态机保存并更新其状态。在环境更新时,通过对比定义差异,决定状态回滚,并根据当前资源状态,编排每个状态阶段的任务。需要注意的是,这种方案在处理"环境更新"时,会有高并发的性能瓶颈,最好采用非阻塞请求。

2.第二阶段:提升构建成功率并降低资源成本

解决了环境自动化构建问题后,Noah 系统每日的环境创建量上百。此时,硬件资源不足和构建失败问题开始频繁影响使用。举个例子,某业务大模版包含应用 80+,数据库 100+。每次创建项目开发环境都需要构建完整的业务环境。此时,受限于宿主机资源,可以并行开发的项目受限。同时,大量环境中的资源属于变更无关,浪费明显。

每次构建规模庞大的完整环境的另一个弊端是构建成功率低,需要人工介入才能确保环境可用。原因也很好理解:环境构建图中每个资源的每个步骤如果成功概率 0.95,则环境单次构建成功概率为 n * 0.95,必然只会更低。此时,Noah 系统的第二阶段着重于解决资源占用与构建失败问题。

为此,我们尝试了多种解决方案:

销毁策略与预部署检查方案此处不展开。就容器化改进而言,Noah 的核心构建流程进行了较大规模的重构,最终兼容了 KVM 与容器的混合部署。下图说明了改造前的虚拟机应用构建流程。其中 "Noah-KVM" 负责虚拟机的预创建与池化,是主要差异点。

改造后的容器化应用构建流程如下。其与原流程的最大差异在于,容器的 ip 地址是在发布过程中分配的,而虚拟机的 ip 在预创建时即可获得。这就导致部分依赖实例 ip 的操作需要重新调整执行时机。另一个显著的差异点是容器镜像的引入。但类比虚拟机的定制任务,镜像本身的构建反而对现有构建流程影响有限。

经过上述方案的尝试,最终的解决办法还是回到了降低环境构建规模上。在 2021 年公司基础架构部门着重实现"软路由机制"(也称"泳道环境"、"智能路由"),解决测试业务领域的环境构建与问题排查困难问题。

这部分的改造主要是中间件与网关,涉及路由与染色的改造。在环境层面的改造更多集中在"如何识别应用依赖关系实现数据隔离"、"如何提供染色策略与路由标识"。

2.1 关键点1: 如何识别应用依赖关系实现数据隔离

在创建"软路由环境"时,要求存在对应的"基准环境",以便进行依赖关系收集。在添加应用时,若选择隔离数据(新建数据库)则可利用依赖关系实现此应用相关资源的隔离。下面两图展示了当前的隔离方式。

依赖关系的收集有两种渠道:

1、通过环境变量替换机制,上报并收集当前基准环境此应用的变量使用情况。

2、主动请求基础架构 SDK,获取运行时的数据库名称。

随后,合并两种渠道的变量,并根据变量规范与基准环境中资源实际名称的比对,即可实现自动的依赖关系收集。

2.2 关键点2: 如何提供染色策略与路由标识

所谓的染色,在测试环境场景下特指为特定请求携带软路由标识。所谓路由,即通过请求的软路由标识动态选择需要转发的下游应用实例。

使用 Noah 系统构建的环境,会得到一个 env-id 作为环境标识。此标识会在应用发布时被注入其实例的运行环境,并被 SDK 识别,最终带入注册中心。此时,应用在中间件的注册信息中已经完成了环境标记。待软路由请求到达后,会据此实现软(动态)路由。下图对"软"路由过程进行简单说明。图中,蓝色箭头为应用注册,红色箭头为请求链路。

对于 dubbo 和 qmq(去哪儿网的消息中间件)而言,依靠服务治理能力,可以在中间件内部实现路由标识识别与匹配,最终路由到正确地址。但在域名网关中,依据实现不同,有两种路由方案。

其一是测试环境脚本搭建的 nginx。此时使用 tengine 替代原生 nginx,使用其动态更新 upstream 接口配合自定义 lua 脚本可以实现实时染色与路由。下图描述了其 lua 脚本逻辑。

其二则是公司公用的 openresty。其需要通过自定义 lua 脚本实现染色(染色逻辑与 tengine 逻辑基本一致),并通过复制基准规则并改造为软路由规则实现路由。下图展示了一个典型的支持软路由的域名规则页面。

在2021 年底完成软路由改造后,以酒店大模版为例,Noah 环境的平均规模下降 90%。同时在2022 年的降本增效专项中,Noah 宿主机占用成功缩减百余台,有效降低了资源成本每年近百万。同时,环境构建成功率也稳定在 80% 以上。至此,我们基本解决了测试环境核心的两大难题。

3.第三阶段:提升开发效率与降低运维的人力成本

测试环境的生命周期从构建开始,随着使用,最终销毁。在使用阶段,当研发人员推送新的代码分支,需要进行部署测试时,传统的方式是手动选择应用,跳转部署平台,将分支部署到当前测试环境。随后,开启远程 debug,进行测试。

此过程通常会耗费 5~10 分钟。在项目开发阶段,经常会反复修改测试。此时,部署的等待时间会很长,严重影响开发效率。我们通过调研办公网与各机房网络的联通性,论证了将研发人员本地电脑作为测试环境应用实例加入测试环境的可行。据此,与 TC 团队合作开发了 Noah 环境专用的 tomcatServer,用于本地化开发。

下图中,只需要勾选 Noah 环境 Tomcat,填写测试环境名称,即可实现本地化开发。部分情况下,还支持代码热更新。此方式节省了部署流程耗时,有效提升开发效率。

此外,环境使用过程中,环境包含的应用不断上线变更,生产环境也在随时产生变更。当其使用阶段持续很长时间时,控制测试环境与生产环境的差异就更加费时费力,需要投入更高的运维成本。2022 年起,基础平台团队与业务 QA 合作,对环境稳定性建立指标体系,量化 SLA 健康度,使测试环境不好用有了更明确的描述。

下图展示了对部分具体指标的定义。

知道哪里有问题,下一步是如何解决问题。Noah 团队多年解答测试环境不好用问题,积累了丰富的问题解决知识。这部分知识梳理后,很大一部分可以自动化执行。下图展示了部分问题的自愈机制。

截止目前,以 "Noah 团队每周运维投入人力"衡量的运维成本不足 1 pd。对比 Noah 3 平台上线初期 15 pd,成熟期 5 pd,运维成本节约效果明显。同样,QA 也从日常测试环境运维中解放,更专注于其他有价值的工作。最终,依靠三阶段优化,Noah 环境平台实现了无感知的测试环境。

总结

测试环境(非生产环境)作为变更最频繁的环境,本身既要灵活多变,又要稳定可靠。其维护管理始终处于这个矛盾中,无非是根据使用场景与核心目标针对性优化。Noah 平台上线初期,互联网基础设施仍处于 KVM 主导时代,我们通过对环境标准化定义,结合资源状态机与动态编排,实现了自动化的测试环境构建,解决了测试环境构建费时费力问题。随后,在疫情期间,围绕降本增效,实现了容器与 KVM 的混合部署支持,为生产环境容器化积累了经验;同时,经过一年多的持续努力,实现了软路由机制的落地,节约了资源成本,提升了构建效率与质量。最后,我们回归到解决测试环境多变更不稳定的问题上,量化测试环境健康度,并借助多年经验积累实现了自愈。经过三阶段的迭代,基本解决了"测试环境"问题。

问题解决过程中,有两点成功因素。其一是 "Noah 环境平台实现了环境视角的测试环境统一管理,为长时间的测试环境治理提供了切入点"。其二是"用户、领域专家与技术专家团队协作,提供了更有效的解决方案"。

一套测试环境需要对接多个部门的多套系统服务,负责人需要有足够的知识与技术能力才能熟练处理相关问题。传统上此角色通常是 devops 团队,因为他们在构建以应用为核心的流水线上面临着同样的问题,只不过环境是更大规模尺度的应用集合。实际中,QA 作为测试环境的负责人,对其治理有更迫切的需要和更高的要求。通过"环境平台"可以有效分离二者的关注点,为测试环境治理提供载体与空间,同时,为用户提供屏蔽底层技术细节与专业知识的统一操作视图。

此外,测试环境治理实际涉及更宽的业务领域,单人很难面面精通。通过建立各业务技术专家组成的虚拟团队,也可以得到更有效的解决方案,避免闭门造车。

Noah 环境平台基本解决测试环境问题后,未来的迭代方向可能有两个:

1、横向扩展,覆盖生产环境的管理,提供全环境视角的统一操作平台。

2、纵向扩展,与 OKR 和 PMO 深度联动,打造需求、开发、测试、上线的价值交付工作流。

我们会继续努力,同时感谢所有为测试环境治理与 Noah 系统做出过贡献的小驼。

以上就是本次分享的所有内容,最后为大家带来一个内推信息,欢迎优秀的你加入驼厂~

【内推链接】:app.mokahr.com/recommendat...

相关推荐
qq_17448285757 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
锅包肉的九珍8 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦8 小时前
Scala的Array(2)
开发语言·后端·scala
2401_882727578 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
心仪悦悦9 小时前
Scala中的集合复习(1)
开发语言·后端·scala
代码小鑫9 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖9 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶9 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
uzong10 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
飞升不如收破烂~11 小时前
Spring boot常用注解和作用
java·spring boot·后端