一、导语
在服务实例数量和规模较大的业务场景下,服务路由是系统比较常见的诉求,比如针对业务属性的全链路灰度、测试环境多分支路由、多Region多AZ时的就近路由等。TSF基于标签化能力完成流量染色和标签自动传递,仅通过控制台配置即可实现服务路由、全链路灰度及就近路由功能,快速满足客户的业务分流诉求。服务路由从行为上讲,是将流量进行染色区分,并通过路由规则将流量进行分流,本节将对TSF整体服务路由相关能力进行详细介绍。
二、作者介绍
崔凯
腾讯云 CSIG 微服务产品中心产品架构师
多年分布式、高并发电子商务系统的研发、系统架构设计经验,擅长主流微服务架构技术平台的落地和实施,目前专注于微服务架构相关中间件的研究推广和最佳实践的沉淀,致力于帮助企业完成数字化转型。
三、治理路由
功能说明
本文中“治理路由”特指TSF中的“服务路由”功能,主要为了区分广泛意义上的服务路由。治理路由的配置参数包括:
-
流量来源配置:标签类型、标签名、逻辑关系、值;
-
流量目的地:所在应用、目的地类型、部署组/版本号、权重。
简单总结:通过判断请求中标签(key)对应的值(value)是否符合治理规则的配置,进而通过配置的权重比例将请求转发到指定的部署单元,如不同的部署组或版本。
配置过程中需注意如下情况:
- 填写治理路由规则需要在服务提供方进行配置,例如A服务调用B服务,需要在B服务上配置治理路由规则。
- 对于Spring Cloud服务,配置治理路由规则后,若配置的目标部署组无法运行,流量将按照原有默认的轮询方式分配到其他部署组上。
- 对于Spring Cloud服务,当服务提示未绑定应用时,需要在服务详情页单击编辑后绑定服务,才能开始配置治理路由规则。服务绑定应用操作,一经绑定,不能修改。
- 要使治理路由规则生效,需要确保在控制台开启了待生效规则,并在代码中添加了路由的注解。
- 对于Mesh应用,配置路由规则后,若配置的目标部署组无法运行,则路由规则配置失败,请求无法发送。
配置生效后,可以在列表项的流量分配图中查看流量分配情况,如下图所示。此时注意,配置了流量的权重比例后,要使路由准确性达到预期,请求数至少要在1000以上;如果请求样本数不高的情况下偏差会比较大,样本数越高准确性就才越高。
容错保护
在使用治理路由时,TSF还具有容错保护的功能来规避一些场景。假设针对provider服务分配了两个版本:V1版本承载10%的流量,V2版本承载90%的流量,并针对上述流量分配进行了对应的治理路由的配置。此时,如果V1版本所有实例全部故障,那么就会有10%的流程报错,这是业务不能接受的。
此时可以使用容错保护功能,当在provider服务的治理路由界面打开容错保护功能时,TSF-SDK发现V1版本的所有实例都不可用,会尝试将流量路由到目前所有可用的实例上(即V2版本的所有实例)。待V1版本实例从故障中恢复,容错保护无需手动干预,即可将流量重新按照V1版本10%+V2版本90%的比例分配。
适用场景
治理路由能力从上述功能描述可以发现,它更着重对于单个或少数服务的路由进行管控,且对上下游服务的自定义标签传递没有强诉求,因为治理路由可以使用TSF系统标签做判断。所以,治理路由更适合少量串联服务并需要单独配置的路由场景。
测试环境多分支场景
往往客户资源有限的情况下,只有一套测试环境。当该环境正在进行feature版本的开发及测试时,如果突然需要修复生产环境的一个重要BUG,且当天上线这个hotfix版本。那么测试人员需要把hotfix版本涉及的服务重新发布,并覆盖现有测试环境中正在测试的feature版本。并且在hotfix版本上线后,将feature版本重新发布到原有资源上。除了资源替换产生的额外成本,还会产生版本覆盖前后记录上下文、更换环境配置等额外成本。
那么我们如何解决呢?我们可以通过在测试环境创建hotfix版本的部署组资源并完成部署,同时通过治理路由规则+标签化参数的方式,使得添加“feature”参数的请求调用feature分支服务,添加“hotfix”参数的请求调用hotfix分支服务,实现测试环境多分支并行测试的目的。在最终测试完成hotfix版本后,直接释放hotfix分支使用的资源即可,不再需要进行版本替换和上下文更新,极大节省运维成本、提高测试效率。
配置步骤:
- 测试请求需在Path、Query、Header或Cookie中任一位置携带tag参数,指定分支版本信息(feature或hotfix);
- 在微服务网关中新建Tag插件,配置Tag转换规则,并将Tag插件绑定网关分组;
- 新建Service B、Service C的hotfix版本部署组,并完成应用发布;
- 在Servcie B及Service C的服务治理->服务路由中新建路由规则,保存并开启。
当在控制台开启治理路由规则时,规则会对应用实时生效。通过上述步骤即可快速实现测试环境多分支的治理路由配置。另外,假设Service C关联了更多的版本/部署组(如4个),则只需针对Service C进行路由规则的添加即可,并不影响Service B的路由配置。
四、全链路灰度
功能说明
随着系统架构向微服务转变,应用的发布频率和次数都明显增高。尤其当微服务的规模越来越大,如何能够在保证低运维成本、故障爆炸半径可控的情况下,完成全链路大规模的发布动作,成为研发及运维部门面临的难题。
全链路灰度是软件逐步上线常用的发布方式,是指将具有一定特征或者比例的流量,逐步分配到指定版本的过程,通过生产流量实测发现新版本可能存在的潜在问题,同时将故障损失控制在灰度范围内。
相比全量上线,灰度发布是更加谨慎的发布形式。当线上调用链路较为复杂时,全链路灰度发布可以将生产环境隔离出一个逻辑独立的运行环境。同时,全链路灰度的泳道可以反复使用,即使进行变动也比较灵活,使得全链路灰度的运维成本也缩小很多。
使用全链路灰度发布之前,需要先配置泳道。一条泳道相当于一个灰度环境,环境中包含应用中需要进行灰度测试的部署组。
泳道:泳道是一组业务关联的部署组的集合,是灰度流量的目的地。泳道中的部署组属于不同的应用,可以认为用户通过划分泳道而划分出了灰度环境。
灰度规则:用户新建灰度规则以设定灰度流量应满足的条件。当灰度规则判断请求满足条件后,会通过灰度规则将流量路由到某一个泳道中。
泳道入口:
在全链路灰度发布模块中发布灰度规则时,会在泳道的入口部署组上对请求进行灰度规则校验,以此来判断请求是否应该进入某一个泳道中。泳道入口可以是一个微服务网关,也可以是一个微服务。
同一个泳道中支持多个入口,在请求经过每一个入口部署组时,都会判断请求是否应该进入泳道中。
TSF全链路灰度发布的操作流程如下图,详细操作步骤可浏览TSF官网进行查阅。
https://cloud.tencent.com/document/product/649/43463\
全链路灰度流量流向规则与说明
- 当泳道上已经绑定了全链路灰度发布的规则,则不能删除泳道。
- 当请求流量没有命中任何灰度规则,流量将走到没有被添加到泳道的部署组中。
- 当某一个微服务下的部署组没有被加入任何泳道中,请求将在该微服务下所有部署组的所有实例中轮询。经过该微服务后,请求将继续按照规则流入对应泳道。
- 一个部署组可以属于多个泳道。
- 在泳道中,服务路由规则不生效。
- 泳道是一个隔离环境。当泳道上所有规则关闭后,流量不会进入泳道中。如希望恢复建立泳道前的流量分配方式,请将泳道删除。
全链路灰度中消息主题染色
kafka作为主流的消息队列产品之一,经常用做业务逻辑间的解耦及大数据场景。那么在全链路灰度发布时,服务间调用如果使用了kafka做异步解耦,在消息未被染色时就会出现Consumer错误的消费了其它泳道消息的现象,这是业务不能接受的。
TSF通过将泳道标记在线程中向下传递的方式实现消息染色,即染色流量能在流经kafka后被对应泳道中的部署组消费,而未染色消息被不在任何泳道中的部署组消费,并且泳道标(即LaneId)能在消息流经kafka后继续传递给下游服务。详情请参见官网最佳实践:https://cloud.tencent.com/document/product/649/75454
适用场景
全链路灰度发布是大规模微服务架构场景下几乎必备的发布方式,它可以满足指定小流量验证、逐级切流控制故障范围、多个关联服务一次性共同发布、一次配置反复使用等要求,有效减少了发布成本及上线变更带来的风险。
基于地域和用户的灰度测试场景
互联网产品经常会邀请公测用户进行体验,当产品需要上线新功能时,希望使用灰度发布的手段在小范围内进行新版本发布测试。在测试一段时间后,逐步的增加新版本的流量比例,同时减少原有版本的流量比例。上述这种灰度发布的模式,不同于以往新旧版本发布的一次性切换,让整个发布过程通过灰度发布的方式进行过渡。
通过TSF进行如上场景的全链路灰度发布流程步骤如下:
- 创建并部署微服务网关;
- 创建全部待灰度部署组并发布;
- 创建微服务网关分组、导入API并发布分组;
- 新建微服务网关插件并绑定分组;
- 新建泳道,并在泳道中添加全部灰度部署组,并设置网关为泳道入口;
- 创建灰度发布规则并设置为生效状态;
根据如上配置,当用户发起的请求包含region=beijing、usertype=testUser的参数(代表北京地区的公测用户)时,则会进入所配置泳道部署组,实现全链路灰度的发布操作。
同时在配置及运维过程中需注意:
- 评估单个provider服务实例可以处理多少请求,并根据流量分配来规划部署组的实例数量。
- 如果流量比例变化后,可能需要调整部署组的实例数量来满足新的流量。
- 可以通过设置弹性伸缩规则来支持动态调整实例数量。
- 全链路灰度发布支持同时生效多条规则,并支持为规则配置优先级。当同一条请求同时满足多条规则时,会优先匹配高优先级的规则。
五、单元化
功能说明
单元化架构主要是为了解决多中心容灾、机房弹性扩容等问题,也可以依托单元化架构实现单元级故障隔离、单元级全链路灰度。本质上讲,单元化架构也是流量路由的一种方式,只不过路由的目的地是每一个平行的业务自闭环的单元(Set)。
如下为两地三中心架构下TSF单元化最佳实践的简要说明:
方案说明:
-
基于智能DNS解析实现域名到地域的IDC机房路由,入口通过调整DNS解析结果,实现跨地域流量切换。
-
通过入口负载->微服务网关,按权重比例配置路由,实现业务应用的同城双活。
-
微服务网关到应用,基于网关的标签化路由规则实现单元化路由匹配。
-
基于本地缓存的单元路由规则进行服务寻址,实现单元路由调用。
注意事项:
- 单元内服务调用尽量在单元内闭环,减少跨单元调用;
- 如果业务需要跨单元调用,由微服务网关管理跨单元请求的转发;
- 业务南北向流量应尽早完成正确单元的路由寻址,出现单元寻址错误时需能够正常重定向;
- 当出现单元化路由KEY不符合任何单元或访问不携带KEY时,可报错或按默认单元化规则处理;
- 针对正常/错误的单元化调用流向,做到可监控、可预警、可管理。
TSF单元化能力主要以 “微服务网关”+“命名空间” 为实现基础。微服务网关主要的作用是单元化规则的路由转发,为了完成这一目的,TSF深度增强了开源微服务网关Zuul及SCG;命名空间是TSF本身具备的能力,分为普通命名空间和全局命名空间,普通命名空间主要用来对服务间调用进行逻辑隔离,全局命名空间主要用于打通特殊的跨普通命名空间的服务调用。
在TSF单元化部署架构中主要使用全局命名空间放置微服务网关,使得微服务网关可以连通多个逻辑单元(普通命名空间)中的服务并进行单元化路由,使用普通命名空间进行各逻辑单元(Set)的隔离,保证每个单元的独立。
单元化改造主要涉及两个步骤:配置单元化、单元化部署,详情官网链接。
配置单元化:https://cloud.tencent.com/document/product/649/55877
单元化部署:https://cloud.tencent.com/document/product/649/55879
适用场景
单元化适用场景主要集中在大规模或超大规模的分布式系统中,同时从企业成本和管理角度讲,整个单元化改造的过程是漫长的、成本是巨大的,实际情况可能是企业内部系统架构在扩展性、可用性、性能存在多方面痛点,不得不通过单元化改造来解决现有问题。
银行业务单元化改造场景
单元化改造中单元化规则的设计是重中之重,且银行业务一般情况不涉及到地域等其它属性,所以主要还是从用户的业务属性出发进行设计。
首先以用户ID尾号为单元化KEY,将用户划分为00-99等量的100个数据单元,此为第一层全局分片规则。而后基于各产品线业务分片需求自定义二层分片规则,如对公对私场景,以用户ID前添加的公/私前缀字符串为KEY进行二次路由计算。通过上述规则设计,实现基于全局+产品线双维度的单元化规则模型。
例如,假设用户标签tag值为:B_20210817,一层标签根据用户ID尾号的“17”进行全局分片路由,二层标签根据对公对私的业务标记“B”(B为对公,P为对私)进行产品线分片路由,最终得出唯一的单元编码(命名空间ID)。
确定单元化规则后,如上述《功能说明》中对微服务网关及相关单元化服务进行代码修改,并按照流程在TSF控制台操作创建单元化规则,即可完成业务的单元化改造。
TSF单元化架构核心价值体现在运维及开发成本、管理效率、高可用容灾、弹性伸缩方面,对比客户自建单元化架构具备运维简单、可用性高、开发便捷、配置灵活的特点,且可与TSF平台本身在诸多功能上进行联动。
对比项 | TSF单元化架构 | 自建单元化架构 |
---|---|---|
运维成本 | 由TSF统一运维,提供企业级SLA支持 | 需企业自身具备较高运维水准 |
开发成本 | 无需开发单元化服务,通过控制台配置实现 | 需企业自实现单元化服务 |
管理效率 | 与TSF整体Paas技术平台统一提供可视化管理,减少跨平台操作 | 代码、配置平台、运维平台等多方面联动管理,无统一可视化界面 |
高可用及容灾 | 依托TSF多年高可用容灾经验积累,拒绝踩坑 | 需逐步完善自身高可用技术及人才 |
弹性扩缩 | 快捷联动TSF自身基于容器、虚机的弹性伸缩和路由机制 | 需要自身配置实现弹性扩缩容机制 |
六、就近路由
功能说明
就近路由主要解决在同城双活或多活场景下,应用在不同AZ有多个冗余部署组时,当某一AZ的应用部署组实例全部故障后,通过就近路由可以自动切换到另外AZ的冗余部署组中。同时,当部署组没有出现故障时,我们会优先访问同AZ的的被调服务,以减少跨AZ的访问延时。通过就近路由可以在保证低延时的同时,提高一定的系统高可用性。
其功能配置比较简单,即在创建命名空间后开启即可(默认开启)。
就近路由的实现主要依托于多个不同AZ的实例是注册在同一套注册中心上,通过consumer和provider服务在注册时上报的信息,我们可以知道实例的所属AZ、Region和部署组版本等信息,TSF-SDK会通过这些信息筛选最合适的实例进行调用。
通过上图可观察到,TSF-SDK会优先判断被调服务是否有实例与主调服务在相同AZ内,如果没有则会对规则降级,继续判断被调服务是否有实例与主调服务在相同Region内,直到最终找到符合就近路由规则的实例。
适用场景
就近路由主要使用在跨可用区容灾场景下,如在广州一、二区搭建同城双活架构,当开启就近路由时,广州一区的consumer会优先调用同一可用区的provider。
此时,当广州一区的provider不可用,consumer会跨可用区调用广州二区的 provider。
更多详细配置请参见:https://cloud.tencent.com/document/product/649/33797
七、结语
路由主要是解决流量如何分类,以及从哪里来、到哪里去的问题,本节通过对治理路由、全链路灰度、单元化、就近路由的功能及实践场景的描述,展示了TSF在流量路由方面的核心能力,基本覆盖了主要的流量路由场景,希望能给读者朋友提供一点帮助。
引用
https://cloud.tencent.com/developer/article/1891503
https://cloud.tencent.com/document/product/649