多分支并行开发模式下,测试环境的相互隔离是确保测试环境稳定性、测试可测性、测试结果可信度、问题排查定位的基本前提。微服务架构模式下,随着业务的不断发展,随之也带来了服务数量不断膨胀、依赖服务庞大,调用链路过长等问题。多需求开发时的环境隔离面临的成本也越来越高,测试环境隔离成了研发效能中无法避开的一项“绊脚石”,于严选业务而言,具体表现为:- 原有部署模式下,分支和集群环境捆绑,多需求并行时,环境争抢严重
- 环境隔离依靠物理(集群)隔离,实例扩容成本和申请配置链路较长
- C端的每套测试环境均配置对应Nginx及API网关配置,配置维护及不同测试环境依赖Host配置切换较麻烦
在此背景下,基于环境治理的大目标并为高效的研发协作夯实基础,环境隔离项目也应运而生。2. 目标
- 通过制定统一的域名规范,减少多套环境对应的Nginx、API网关、WZP、link、Locate等配置依赖成本,摆脱Host配置切换,测试环境新增一套特征环境无需重复申请,追求零配置
- 建立稳定的基准测试环境,提升测试环境的稳定性及可用性,建立起开发、联调、测试特征环境、测试回归等不同环境的访问规范。
- 服务发现支持动态路由,摆脱原多集群进行环境物理隔离机制,不同环境的访问切换不需要更改consul域名,支持跨集群的路由转发。
3. 实现方案
目前业界及网易也已有不少环境隔离的解决方案,在调研后结合QA侧诉求及CICD建设目标严选质量保障与基础技术等团队结合严选架构现状设计出一套试用于严选环境治理的轻成本环境染色解决方案。3.1 核心机制
引入环境染色标签,利用该标签与实例做绑定关联,在请求调用时传递该标签,在进行路由转发时优先用染色标签去匹配实例,不匹配则请求集群下的无色节点作为基准测试环境进行兜底,在此过程中,域名解析、网关及相关中间件配合负责标签的传递、解析及透传。3.2 环境染色的作用域
- 第一阶段仅实现对Http(s)及客户端WZP请求的染色
- MPS(严选消息发布订阅系统)支持染色,实现消息消费隔离
- 染色仅作用于测试环境,回归测试环境(回归环境仅单集群无环境隔离必要)不在染色范围内
3.3 环境染色的定位
环境染色是为了在开发和测试阶段迅速搭建起一套全链路的特征环境。基于这个定位下,染色环境是作为特征环境使用的,与之对应的则是处于平行关系的基准测试环境。一个测试集群可以有1+N个服务实例,但1个实例只能属于一个集群。在测试集群下,除了基准测试环境(集群编码通常为:test)外,至少应增加一套其它集群(如:out-cloud-dye)作为染色的特征环境集群。3.4 线下测试环境规范
4. 分层实现
4.1 实例绑定染色标签
服务治理平台及部署平台提供能力支持按集群或实例维度设置染色值,绑定关系做持久化,单实例支持设置多个染色值。4.2 染色域名规划
原测试环境仅一套域名,不同环境需要通过不同的Host配置(对应不同Nginx配置),API网关也对应多套配置,每套配置对应不同的路由转发地址去实现不同环境的映射。
新规划了一些域名,如:.feature.you.163.com,并为之提供DNS泛域名解析,新域名.feature.you.163.com的*星号位置为染色标签值。原多套Host、Nginx、API网关配置均只需保留一套即可。4.2.1 染色标签设置注意事项
- 染色集群限制
强烈不建议在默认测试集群的实例下打染色标,会导致无色节点请求与染色请求出现环境交叉,与环境隔离的目标相违背。 - 染色标签命名规则限制
染色标签的命名及取值既要具有一定的前瞻性,又要注意合法字符的范围,要求同时遵照DNS+CMDB Cluster+Consul Tag+K8S NS/Label规范及最佳实践,一律小写,避免使用非法字符或敏感字符,如不能包含小数点(域名非法字符)。如合法字符范围:[A-Za-z0-9-]*,本次设置X-YX-COLOR作为染色标签 - consul 环境不可作为color值,如test、regression、online、dev、release、pressure
- 系统特殊字段,如权重字段weight=xx,系统保留字段_yxgw
4.3 网关解析染色域名
运维的测试Nginx网关新增对染色域名(如:.feature.you.163.com)的监听(HTTP和HTTPS均支持),提取域名中星号位置的字符串,即本特征环境的代号,设置一个新HTTP头:X-YX-COLOR: xxx,接着再转发给测试环境的严选API应用网关,若头部已存在则透传。4.4 染色标签在服务间透传
严选链路追踪中间件底层应用CaesarAgent 具备分布式全链路追踪(Tracing)能力,请求流量标识可以实现不同服务节点/消息中间件之间透传。
CaesarAgent复用traceId透传能力,在服务调用时新增支持对X-YX-COLOR: xxx染色标签在HTTP请求头进行透传。这样一来,服务A在调用服务B时,A进程所发起的HTTP请求就会自动带上这个颜色标记,再由A所在机器的Sidecar(云内envoy或云外consul-nginx)根据该标记进行有针对性的转发,以及继续透传。4.5 路由转发
4.5.1 路由转发图
4.5.2 具体逻辑
- 对于无色请求(请求Headers中不携带X-YX-COLOR),将会在当前集群中查找所有可转发节点,包括有色节点(存在多个符合条件的实例则按权重比例分流) ——前面搭建特征环境中提到,染色实例强烈建议不要与默认测试环境(无色实例)在同一集群下,因为若是在同一集群下,无色请求也可能被转发到有色实例下,这样的话做不到环境的完全隔离
- 对于有色请求(请求Headers中携带X-YX-COLOR),优先会在所有集群中寻找带颜色标记的可选转发节(存在多个则按权重比例分流);若没有一个实例符合要求,则会在当前集群中查找无色实例作为可转发节点;若当前集群并没有无色节点则路由失败,返回502
总结起来其实就是一句话:根据源请求的Consul Tag和Color值去动态匹配目标地址,Color优先于Consul Tag,有色请求可跨集群访问,无色请求不支持跨集群访问。4.5.3 染色最小范围原则
对于大多数需求,往往只涉及到调研链路中少量甚至只有一个应用的变动,这种情况下没必要为了环境隔离将全量的应用都搭建一遍,仅对涉及的应用进行染色,其余未涉及改动的应用在染色请求链路中会路由到无色节点实例,即可实现链路环境的隔离测试。- nocolor:实例不带颜色时所需要打的标签,与颜色实例作区分,作为流量的兜底。
- 如流量为green时,当前集群或其他集群 不存在该颜色实例时,会命中当前集群中的nocolor实例
- 如流量为green时,当前集群或其他集群 存在该颜色实例时,不会命中当前集群中nocolor实例
- 如流量不带颜色header时,会命中当前集群中任意一个实例(包括nocolor实例 或 其他颜色实例)
4.5.4 关于非健康实例
有色请求在进行路由匹配时,只要存在带有某个染色标记的实例,不论关联实例是否可用,都视为该服务包含了这个标记。例如:服务A下有color=abc的不健康实例和无色的健康实例,当向A发送带有abc染色标记的请求时,会直接返回502,而不是转发到无色实例。这样做是为了避免实例的健康状态影响到环境的隔离性。4.6 消息的隔离机制
严选中间件团队自研的MPS作为消息发布订阅系统在各业务团队中广泛使用,但部分业务中由于历史原因等仍存在开源消息中间件的使用,如rabbitmq等。面对此现状,为了促使大家将严选业务中使用的各类消息中间件尽早迁移到统一的MPS,我们决定只对MPS做染色支持。由于MPS的发布订阅事件均走HTTP(Consul形式)调用,在染色支持上具备天然的优势,利用CaesarAgent染色标签传递能力直接在消息发布时透传HTTP头X-YX-COLOR: xxx键值对即可,而消息订阅由于是以push consul调用的方式通知订阅方,故消息消费时无需任何改造即可实现路由转发,从而确保消息的正确消费。4.7 移动端wzp染色机制实现
严选移动端使用WZP协议与服务端进行通信。此模式下面临的问题是:每新增一套业务特征环境,需同步配套新增一套wzp环境,成本高。4.7.1 原通信模式
4.7.2 WZP染色方案
通过移动端测试设备id与染色color做关联,测试api网关监听wzp-hp及app中特定域名请求,在请求头中提取设备id,根据设备id绑定的color值,设置一个新header头X-YX-COLOR: xxx以实现染色。
价值可支持测试app内所有请求协议的染色,设备绑定染色标签与业务请求完全解耦,实现一劳永逸。4.8 天枢测试环境隔离
天枢(严选一站式研发协作平台)实现一键为实例打标并部署的能力,使用效果如下。分支上线后自动解除染色标签
分支合并到上线分支并上线后会天枢自动解除分支部署实例关联的染色标签,实例变为特征环境集群的无色节点,用于下次特征环境的需求使用
4.9 异步线程染色机制
4.9.1 显示透传染色标签
在特定场景下,需要在业务代码中显示获取染色参数,比如第三方支付回调的域名需要使用泛域名方式染色时,再比如服务中异步http请求默认会丢失X-YX-COLOR染色标签传递(非必要时不建议对业务代码进行侵入)- 第一步:业务方引用yanxuan-trace-client(apm相关jar)
<dependency>
<groupId>com.netease.yanxuan</groupId>
<artifactId>yanxuan-tracer-client</artifactId>
<version>${tracer.client.version}</version>
</dependency>
- 第二步:显示获取染色参数并使用(建议以Spring AOP等方式做显示染色,减少对业务代码的侵入),Code demo:
if (systemEnvironmentConfig.isTestEnvironment() && StringUtils.isNotBlank(TracerClient.getTagItem("x-yx-color"))) {
String color = TracerClient.getTagItem("x-yx-color");
}
else {
}
5. 未来规划
6. 总结及感谢
研发效能犹如木桶原理,任何一块的短缺都会对研发效能及交付质量产生重大影响。严选效能体系建设需要各研发团队的协作配合,在此感谢基础技术、客户端、前端、服务端等相关团队对QA团队的支撑与配合,共建严选效能体系。