致景科技|一站式动态多环境建设案例

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 致景科技成立于2013年12月,是领先的纺织产业互联网企业,国家高新技术企业。旗下拥有“百布”、“全布”、“天工”、“致景金条”、“致景纺织智造园”、“致景智慧仓物流园”等业务板块,致力于通过大数据、云计算、物联网等新一代信息技术,全面打通纺织服装行业的信息流、物流和资金流,帮助行业实现协同化、柔性化、智能化的升级,构建纺织服装纵向一体化的数智化综合服务平台。

致景科技成立于2013年12月,是领先的纺织产业互联网企业,国家高新技术企业。旗下拥有百布全布天工致景金条致景纺织智造园致景智慧仓物流园等业务板块,致力于通过大数据、云计算、物联网等新一代信息技术,全面打通纺织服装行业的信息流、物流和资金流,帮助行业实现协同化、柔性化、智能化的升级,构建纺织服装纵向一体化的数智化综合服务平台。

方案背景

问题描述

项目测试环境被抢占

伴随着业务增长,项目并行的情况越来越多,之前的一套开发/测试/生产环境串行跑研发流程的方式已经不太适合,典型的问题就是一个项目测试环境经常性被缺陷修复的测试流程抢占,导致项目测试时断时续,对测试而言缺乏沉浸式体验,同时测试环节成为项目并行度的主要瓶颈。


开发联调环境不稳定

开发环境自由发布,经常性导致联调中断,开发转而寻求端到端的线下联调,在个人机器上部署上下游应用,这种模式在微服务化推广之后面对众多的微服务应用基本上寸步难行。如何解决开发阶段代码调试?


线上灰度环境的缺乏

缺乏专门提供给产品经理进行功能验证的预发环境,新功能直接上线到线上环境,研发团队经常性地将发布计划安排在晚上以避免对客户产生不良影响。线上缺乏灰度发布能力,新功能上线以后对全量用户放开,在有产品设计缺陷或者代码漏洞的时候,影响面是全网的,风险巨大。


问题综述

线下缺乏隔离的多套环境来支持多项目的开发和测试,线上缺乏灵活的流量路由策略支持灰度。


方案调研

我们的目标是开发团队不依赖运维团队(DEV=OPS),可以一键拉起逻辑隔离的开发/项目环境,可以支持预发环境隔离,生产环境规则流量+自然流量的全链路灰度验证。

根据我们对当前问题的分析,参考目前互联网上的解决方案都指向了项目环境治理和服务流量治理的方案,我们稍微罗列下常用的几种方案,我们最终选择的是阿里云微服务引擎MSE标签路由+云效应用交付平台APPSTACK的集成方案。


自研ribbon实现

image.png

在平时的业务开发过程中,后端服务与服务之间的调用往往通过fegin或者resttemplate两种方式。这其中的原理是ribbon组件帮我们做了负载均衡的功能。灰度的核心就是路由,通过重写ribbon默认的负载均衡算法就意味着我们能够控制服务的转发。这个方案要实施下去,对于大厂来说确实可以从0到1再到100进化出来,但是对于创业团队来讲,要达到成熟可应用的阶段,需要投入专门的技术资源,耗费不菲的时间成本。或者就是做一个只支持核心场景的简陋版。


物理隔离(蓝绿发布)

下载 (1).jpeg


这种方案需要为要灰度的服务搭建一套网络隔离、资源独立的环境,在其中部署服务的灰度版本。由于与基础环境隔离,基础环境中的其他服务无法访问到需要灰度的服务,所以需要在灰度环境中冗余部署这些服务,以便整个调用链路正常进行流量转发。此外,注册中心等一些其他依赖的中间件组件也需要冗余部署在灰度环境中,保证微服务之间的可⻅性问题,确保获取的节点IP地址只属于当前的网络环境。这个方案需要为这些业务场景采用堆机器的方式来维护多套灰度环境,会造成运维、机器成本过大,成本和代价远超收益;如果应用数目很小,就两三个应用,这个方式还是很方便的,可以接受的。


MSE标签路由+ APPSTACK应用编排(我们的选择)

这两款产品的说明文档见链接:

  1. 云效应用交付平台 AppStackhttps://help.aliyun.com/document_detail/321856.html
  2. 阿里云微服务引擎MSE 标签路由https://help.aliyun.com/document_detail/170454.html

我们假定通过上面的两篇文章,读者已经对这两个产品已经有了简单的了解:APPSTACK负责应用的环境管理和流水线发布,MSE负责流量全链路灰度。


MSE标签路由的重要概念

对照下面的MSE标签路由的图,我们重点介绍下MSE标签路由的几个重要概念如应用的打标、流量染色/自动染色、标识链路传递等,同时下图也是我们采用方案的核心原理,使用域名来标识不同的逻辑隔离环境。

image.png

应用(服务)打标

对照核心示意图,我们发现每个应用都有个(base/gray)的tag,有了这个tag,我们才可以根据tag定义流量规则;

我们创建MSE 应用的时候是通过特定annotation(alicloud.service.tag=dev1)和环境变量spring.cloud.nacos.discovery.metadata.version给MSE 应用打标的,比如通过annotation打标之后我们就可以在MSE的标签路由中进行流量规则定义;

同时我们也可以看到Nacos里面的服务有了一个标签相关的元数据(_micro.service.env_);

image.png

image.png

MSE 流量规则配置

image.png

Nacos 里面元数据信息


也有额外增加一个容器环境变量的做法spring.cloud.nacos.discovery.metadata.version,这种做法会在Nacos的服务元数据中增加一个version属性,像MSE云原生网关就会借助这个version属性进行流量管理,而MSE标签路由则还是借助alicloud.service.tag定义的标签进行流量管理。

image.png

容器中增加 gray 相关的环境变量

image.png

MSE 流量规则配置出现 gray 节点

image.png

Nacos 里面有gray环境的元数据信息

image.png

MSE 云原生网关可以选择 gray 版本


流量染色/自动染色

简单讲,流量染色就是流量带上了特别的标识,对于HTTP请求来说,是请求头里带了一些标识信息,对于Message来说,是消息头里带了标识信息;我们这里主要讲下HTTP流量染色问题;一种是人工的往HTTP请求里面增加标识信息,比如前端请求后端API的时候,增加一个xx:111的标识信息,那我们就说这个流量被染色了。而自动染色,则说的是一个没有标识的HTTP请求,经由某个打了标的nacos服务之后,往后调用下一个服务的时候,自动会带上这个nacos服务的标签信息在请求头里;最简单的举例就是a应用调用b(gray)应用,那b应用调用后面的c应用的时候,会自动带上x-mse-tag:gray的请求头,这就是自动染色。

这里特别提到x-mse-tag:xxx这个标识,他是MSE系统保留的标识,不仅仅代表了染色,同时也代表了链路传递(这个请求链路上的各个节点都会依次传递这个标签下去)和默认的路由规则(优先选择xxx标识的服务,没有找到的情况下,再选择base服务-没有打标的),这个默认路由规则是不需要显式定义的。

我们的解决方案也是特别地利用了这一点,对照核心示意图,我们在域名名字中添加了流量标识,然后在Ingress-Nginx中将流量标识解析出来然后通过x-mse-tag:xxx的方式一路传递下去,这样就实现了在整个链路上优先选择xxx标识的服务,使用没有标识的base服务进行兜底。


标识链路传递

流量被染色,也就是请求头中有特定标识之后,这个标识在调用链路中如何可以传递下去,比如一个HTTP请求,带了user-id:100的头,陆续需要经过A->B->C。即调用A的时候带了user-id:100,A调用B的时候也希望可以带上user-id:100的请求头,同样B调用C的时候也要带上user-id:100。这个就是标识的链路传递,有了这个标识链路传递,我们才可以在为A/B/C应用定义按user-id的值进行路由的策略。MSE的标识链路传递的方法是定义环境变量alicloud.service.header=x-user-id,在入口应用A(所有版本,gray+base)增加该环境变量以后,往后的调用B和C的过程中,都会自动添加请求头x-user-id进行传递,这样就方便我们在A,B,C节点按照特有规则进行路由定义。当然x-mse-tag这个特殊的请求头默认就是链路传递的,MSE会把这个标识层层传递下去并进行默认的路由规则(tag优先,base兜底);MSE标识链路传递的原理如下,借助分布式链路追踪的框架的实现方式,每个应用的探针拦截请求并解析标识,然后暂存到线程空间,在往后调用的时候再通过探针把标识塞到下个请求。通过分布式链路追踪的框架完成标识传递。


下载 (10).jpeg

阿里云效应用交付APPSTACK简述

把云效APPSTACK引入进来,主要目的是方便开发同学通过白屏的管理方式自助完成MSE所需要的配置工作,同时在微服务架构下,我们希望应用进行拆分之后,每个应用都有自己的owner。

通过APPSTACK我们可以屏蔽K8S的deployment,service,ingress等细节,研发同学面向的就是应用+环境+流水线。这样最终开发人员在APPSTACK通过流水线完成应用的环境部署,每个环境都会按照MSE标签路由的中打上不同的标识。

在这里我们不展开讲述APPSTACK的核心功能,我们这里主要的就是借助应用编排,让每个应用的每个环境部署的时候,可以设置好MSE标签路由所需要的各种环境变量和annotation。

image.png

image.png

应用的多套环境部署

image.png

每个环境都会按照 MSE 标签路由的要求打上不同的标识


我们的解决方案

环境定义

通过对阿里云微服务引擎MSE标签路由和云效应用编排APPSTACK的调研,结合我们前面提到所面临的问题,我们最终定义了我们整个研发体系所需要的环境体系即:多套的开发环境(含基础环境)+多套项目环境(含基础环境)+(集成)测试环境+预发环境+(支持灰度)生产环境,如下图

image.png

多套开发环境,目标是支持多个项目的在开发阶段的开发联调,核心要求是各项目动态隔离并且支持端云互联,项目动态隔离是每个项目都有自己的开发联调环境且只需部署有变动应用,端云互联是开发可以将自己本地跑的应用注册到这个MSE这个体系里面来,实现可以本地调试的目的,两个研发可以点对点地进行本地debug来跟踪问题。开发基础环境是负责兜底服务调用的,每个应用生产部署之后都需要同步更新开发基础环境,保障基础环境是最新的生产版本。

多套项目环境,目标是支持耗时较长的大型项目,比如重大技改,重大业务项目,需要长时间占用测试环境跟内外部关联方进行稳定测试的。核心要求是各个项目动态隔离。关于项目动态隔离的定义同上

测试环境,目标是支持短平快的项目测试和集成测试,比如日常的缺陷修复,或者多个小项目需要集成到一起发布,同时也是我们日常自动化测试的环境。项目环境中的特性分支也需要经过测试环境的自动化测试才可以上线。

预发环境,目标是支持产品经理在真实环境中验证产品功能,进行验收,预发环境使用的基础建设如数据库等同生产环境是一致的,当然这里对系统设计也会提出更高的要求,比如需要保持向前兼容,就像数据库,只能增列不能减列,不能在sql中使用select * 等等,这些我们通过DMS进行数据库结构变更的约束和通过代码检查保障,此处不赘述。

生产环境,目标是支持规则流量+自然流量的全链路灰度,这里的规则流量指的是带有明显特征的流量,通过MSE的流量规则能够清晰定义的请求,比如请求头,参数,cookie,body中数据符合规则的。自然流量则相反,我们不指定任何特征,比如全部流量的1%导入到灰度环境,这个我们就理解成自然流量。

综合来看,目前的环境体系里,开发环境和项目环境涉及到动态隔离,所以需要部署基础环境来完成服务兜底的能力,这个基础环境也就是MSE标签路由中无标签(base)应用的提供者。


这一套环境体系的流转流程主要有:

1. 拉取特性分支进入开发环境进行本地开发和前后端联调,然后提测到项目环境

2. 项目环境由测试团队完成功能测试之后,将应用部署到(集成)测试环境

3. 在(集成)测试环境同其他特性分支一起完成集成,并通过自动化测试和简单验证,既可部署至预发环境

4. 产品经理在预发环境进行功能验收测试,通过之后可以发布到生产环境进行灰度验证

5. 在生产环境可以按照规则流量+自然流量进行灰度验证,通过之后就可以导入全部流量

6. 最后将特性分支合并至主干后用最新的生产版本更新开发/项目基础环境。


主要场景实施

场景一:项目隔离的动态多环境

按照我们的解决方案,项目环境要实现的是逻辑隔离的动态多环境,相当于每个应用我们要通过APPSTACK部署基础环境(负责兜底的无标签base应用)和动态项目环境(有变更的)同时我们需要保障前端调用后端的域名可以转换成x-mse-tag的请求头。

image.png

1. 通APPSTACK部署好有标签的应用(项目环境)和没标签的应用(基础环境),下列截图仅做示范

image.png

image.png

1. 在ingress-nginx中解析域名中的tag属性转换成x-mse-tag请求头链路传递

通过ingress配置携带header方式到api网关。

image.png

通过注解nginx.ingress.kubernetes.io/configuration-snippet实现,具体如下:

metadata:

annotations:

nginx.ingress.kubernetes.io/configuration-snippet: proxy_set_header x-mse-tag dev1

通过这样简单配置之后,前端调用后端服务的时候,只要通过特定的域名请求,那ingres-nginx就可以把这个域名对应的请求自动添加一个x-mse-tag的请求传递到api网关应用,然后借助这个x-mse-tag的特殊请求头,在调用下游服务的时候,就会一路优先选择dev1标签的服务,没有dev1标签的服务就会去找兜底的base服务。


场景二:规则流量全链路灰度的生产环境

1、通过APPSTACK在生产环境部署好有灰度标识的应用,略图。

2、定义流量路由规则,在MSE控制台为本次灰度链路中的入口应用设置流量路由规则,比如本次发布更新了A-B-C三个应用,A就是入口应用。

image.png

image.png

通过这种方式定义之后,我们可以设置符合某些特征的流量进入到A应用的gray版本,并且向后层层传递过去,不用每个应用重复设置路由规则。这就会满足了规则流量的全链路灰度的要求。


场景三:自然流量全链路灰度的生产环境

1. 通APPSTACK在生产环境部署好有灰度标识的应用,略图。这里至少需要为本次项目的入口应用A(也可以是全部应用)增加一个自动染色的变量profiler.micro.service.tag.trace.enable=true,这个变量会把经过这个入口应用A的流量自动染色,往后传递的时候自动增加x-mse-tag的请求头,从而实现全链路灰度

2. 定义流量规则,即自然流量的多少比例进入gray环境

image.png

image.png

原理概要介绍

MSE + APPSTACK的解决方案,核心的地方在于流量规则的定义以及流量标识的传递,其核心的解决方案在于流量中标识的解析和传递,我们再看一次这个标识传递的图

image.png

怎么样才能实现这里面最核心的解析Extract和注入Inject的功能呢?

答案是探针,为每个MSE管理的应用运行时候增加一个java agent的探针,完成一个类似JVM AOP的能力,在ACK(k8s)的容器中,MSE通过如下的方式自动为应用安装java agent;

1. 配置 Webhook,然后根据 Pod 或者 Namespac中的 Labels,来判断是否要挂载 Java Agent。如果需要挂载,则就对 Pod 的声明⽂件做出后续修改

2. 获取并添加环境变量 JAVA_TOOL_OPTIONS,⽤于加载 Java Agent。

3. 给业务容器添加 Volume,⽤于存储 Java Agent 的⽂件内容。

4. 给 Pod 添加 Init container,⽤于在业务容器启动前下载 Java Agent

最终我们每个被MSE管理的应用在POD层面可以看到如下信息

image.png

image.png

有了这个探针,我们可以拦截所有HTTP REQUEST的处理类,将我们关心的标识信息暂存起来,然后在应用内部消费Nacos服务的时候增加MSE支持的路由逻辑,选择合适的服务provider(比如是打了gray标的),同时在调用这个provider的服务的时候,可以将暂存的流量标识带在请求头里继续传递下去,大体上跟我们最开始提到的自研ribbon的方式相似。不过MSE在这块做得比较成熟,同时不单单支持了HTTP REST这种服务调用方式,还包括了RocketMQ的消息灰度等。当然标签路由仅仅是微服务引擎MSE一个很小的功能,微服务引擎MSE(Microservices Engine)是一个面向业界主流开源微服务生态的一站式微服务平台,提供注册配置中心(原生支持Nacos/ZooKeeper/Eureka)、云原生网关(原生支持Ingress/Envoy)、微服务治理(原生支持Spring Cloud/Dubbo/Sentinel,遵循OpenSergo服务治理规范)的能力。有兴趣的同学可以看看官方文档,作为创业团队来讲,能够快速具备一站式解决服务治理问题,是一件非常酷的事。像我们部门研发团队,没有专门的运维团队,将近100号产研,每个开发人员都可以深入了解每个产品的来龙去脉,其实是一件很有意义的事情。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
资源调度 前端开发 API
Kiwi-国际化全流程解决方案
目前有很多成熟的库可以帮助前端去做对应的国际化方案,比较知名的有 react-intl 以及 I18N-loader。这些库都可以很好的解决代码中多种语言切换的问题
Kiwi-国际化全流程解决方案
|
4月前
|
存储 数据可视化 大数据
从零到一建设数据中台 - 应用场景及实施路径
从零到一建设数据中台 - 应用场景及实施路径
132 0
|
5月前
|
开发框架 运维 前端开发
构建一体化运维平台的八大功能
【6月更文挑战第6天】构建一体化运维平台的关键8个基本功能。
|
6月前
|
人工智能 运维 搜索推荐
精准选型!企业CRM系统选型指南携手十大功能解析
# CRM系统十大功能概览 CRM系统超越了基本的数据库和商机管理,涵盖线索管理、销售自动化、联系人和客户管理、工作流自动化、营销自动化及AI人工智能助手。它优化销售流程,自动化重复任务,支持客户细分,线索培育,市场活动管理和销售预测。AI功能提供销售预测和异常检测,助力企业提升效率和洞悉市场趋势。此指南为企业选型CRM系统提供参考。
68 1
精准选型!企业CRM系统选型指南携手十大功能解析
|
12月前
|
运维 算法 安全
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——4. 特色研发能力
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——4. 特色研发能力
348 1
|
12月前
|
运维 搜索推荐 API
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——9. 开放能力:自由拓展,满足企业个性化需求
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——9. 开放能力:自由拓展,满足企业个性化需求
289 0
|
弹性计算 运维 Kubernetes
《2023云原生实战案例集》——02 零售/电商/本地生活——厨芯科技 加速业务容器化进程,成功实现增效降本
《2023云原生实战案例集》——02 零售/电商/本地生活——厨芯科技 加速业务容器化进程,成功实现增效降本
|
SQL 数据采集 运维
Dataphin V3.7 版本发布!通过国产化适配、数据研发体验优化、数据治理能力提升和标签平台,帮助企业加速构建数据中台
本次发布的V3.7版本中,Dataphin重点围绕资产建设平台的易用性及可交付性、资产治理平台的完备性以及基础平台的稳定性和开放性进行优化与升级。通过国产化支持适配、数据研发体验优化、数据治理能力提升和标签平台,帮助企业加速构建企业级数据中台,轻松拥有好数据!
Dataphin V3.7 版本发布!通过国产化适配、数据研发体验优化、数据治理能力提升和标签平台,帮助企业加速构建数据中台
|
6月前
|
Java 测试技术 Nacos
一站式动态多环境建设案例
本文介绍了致景科技使用MSE全链路灰度的最佳实践。
一站式动态多环境建设案例
|
监控
《构建立体化的监控体系——58集团监控实践》电子版地址
构建立体化的监控体系——58集团监控实践
60 0
《构建立体化的监控体系——58集团监控实践》电子版地址