开发者学堂课程【微服务治理之全链路灰度:微服务治理之全链路灰度】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/973/detail/14894
微服务治理之全链路灰度
sdk在客户体验方面因为业务代码需要感知到sdk的逻辑,并且需要开发人员去维护,所以体验相对较差,稳定性也比较低。这相当于模改了开源的开发框架,重新编写了一些新的路由逻辑,这导致会覆盖一些开发框架原生的逻辑,稳定性需要由开发者自己保定。
支持成本比较低,因为是以sdk的形式进行集成。白盒由于sdk由业务方自己实现,自主可控,性能基于S P I的动态加载,性能比较高。
JavaAgent是无感知的,是无侵入的方案。支持成本中因为可能会去占用一些额外的计算逻辑,是无信用的,客户代码不透明,所以它是一个黑盒。但是性能比较高。多语言这方面目前只支持java。
Mesh是在每个服务旁额外部署了一个proxy,然后proxy去拦截服务的所有的入口和出口流量,也是一个无侵入的方案,并且它是一个语言无关的方案。白盒程度很低,因为用户不了解proxy的实现。性能方面相比于前有的方案比较低,因为在整个链路中,每经过服务链时流量都会被转移到这个proxy。稳定性高:因为如果想要在真实业务场景去落地istio的话,需要对开源进行做改造,成本很高。
可以使用阿里云MSE服务治理,帮用户做这一切。Mesh也可以,如果不想去操作service mesh 的整体,不管是部署还是成本都很高。可以试用一下阿里云服务网格ASM产品,它在产品化上和用户友好上都做了很大的提升。
五、流量入口:网关
流量入口对网关的要求比较高,因为在全链路灰度的场景中要求微服务网关具有丰富的流量治理能力,需要支持路由。因为后端服务可能有v1v2版本希望网关能够去通过一些匹配规则路由到对应的版本上,需要对一些特定路由规则的请求进行动态达标。如果某些经过前端流量无法进行一些流量染色,那么经过网关时可以由网关来进行自动染色,需要用到网关的一些头部控制能力。
接下来是入口服务可见性问题,因为在架构中采用的注册中心不同,所以要求网关能够支持多注册中心。安全性是指网关能够对入口流量进行统一的认证健全,保障业务系统不被非法流量入侵。
一般情况下,业务会采用流量网关加微服务网关两层架构,微服务网关主要负责南北向流量调度和一些安全防护,在每个集群里会额外部署一个微服务网关做东西向流量以及一些治理。与业务比较紧耦合。在容器跟k8s主导的云原生时代,ingress成为k8s生态的网关标准,使得流量网关和微服务网关二合一成为可能。针对此场景,出于减少用户成本、能力不打折下支持流量治理、服务发现、认证健全、安全控制这些能力,将网关合并成一层,不仅可以节省50%的资源成本,而且可以降低运维及其实用成本。
更重要的是原生网关可以支持与后端微服务治理联动实现从端到端全面的灰度,无论后端采用的是基于javaAgent的方式,还是采用服务网格,网关都无缝支持。
阿里云MSE原生网关
1. 低成本
2. 高性能
3. 高可用
4. 高集成
5. 高扩展
六、从0到1实践全链路灰度
场景一:
如下图所示::
业务场景一现在有三个服务:ABC三个java服务,使用注册中心NACOS。每个服务都有一个灰度版本,对于正式版本的正式环境的服务,通过base.example.com来访问。对于灰度环境这些服务通过gray.example.com访问。
那么如何通过云原生网关和MSE服务治理来实现流量控制问题呢?
首先需要确保已经有原生网关并且开启了MSE服务治理,还要有一个ack集群,并且需要安装mse pilot。
另外需要NACOS注册中心,因为ABC三个后端服务使用NACOS做中心。
并且需要一个云原生网关,从端到端的去实现全链路灰度。
图上是已买好的网关。之后关联已有的NACOS,通过网关通知服务来源。
之后在集群test-yang-1上进行部署三个服务,此处演示kubectl的操作。截取一段代码演示如下:
strategy:
template:
metadata :
annotations :
alicloud.service.tag: gray
msePilotCreateAppName: spring-cloud-a
labels:
app: spring-cloud-a-new
spec :
containers :
env:
-
name: LANG
value: C.UTF-8
-
name: JAVA
_
HOME
value: /usr/lib/jvm/java-1.8-openjdk/jre
-
name: profiler.micro.service.tag.trace.enable
va
lue: "true"
-
name: spring.cloud.nacos.discovery.server-addr
value: mse-455e0c20-nacos-ans.mse.aliyuncs.com: 88
4
8
-
name: spring.cloud.nacos.discovery.metadata.version
value: gray
代码mse.yaml中ABC三个服务都有base和gray版本,注册中心需要换成自己的注册中心。对于入口服务A,因为云原生网关对于路由需要版本标,在业务容器的环境变量中使用节点打标的技术为入口服务进行环境打标。同时需要开启mse的链路传递去传递灰度标。
代码所示的tag使用pod注解的形式来打。
现在需要apply该资源。
输入k apply -f mse.yaml
结果如下
输入k get pod
结果如下
等到全部运行状态为running时,可以看到A有两个服务,B也有两个不同版本,C也有两个不同版本。
回到云原生网关将服务A导入
接下来创建两个域名,我们希望base.example.com流量访问到ABC的正式环境,gray.example.com流量访问到ABC的灰度环境。
创建域名:
然后在服务列表中关联版本,点击添加新版本,版本名称为base,标签名为version,标签值为base,保存成功后再创建gray版本:版本名称为gray,标签名为version,标签值为gray,保存。
创建成功后创建路由:
目标服务选择标签路由,添加目标服务sc-A,版本base,权重100,创建完成后点击发布。
发布成功后进行访问,在代码中输入
curl -v -H “host:base.example.com”118.31.118.69/a
可以看到请求是ABC,流量在正式环境中流转,再访问还是ABC。接下来访问灰度环境的域名:
创建灰度环境的路由,路由名称为gray,关联域名为gray.example.com,路径为精确匹配,匹配值为/a,添加目标服务为标签路由,服务为sc-A,版本为gray,创建完成后进行发布。
再在代码中输入:
curl -H “host:gray.example.com”118.31.118.69/a
显示结果ABC都在gray环境中。
场景二
场景二的业务只有一个域名,没有灰度域名,那么可以在前端访问流量时带上灰度标识x-mse-tag:gray,代理该流量标的请求路由到灰度环境并且在整个灰度环境中流转。
回到云原生网关,下线gray路由,再创建路由,路由名称为tag.gray,关联域名为base.example.com,匹配路径为精确匹配,值为/a,在请求头上添加一个匹配,Header Key为x-mse-tag,条件为精确匹配,值为gray,添加目标服务,服务为sc-A,版本为gray,创建成功后发布。
首先来访问正式环境不带tag标识:输入
curl -H “host:base.example.com”118.31.118.69/a
结果显示正常ABC流向,再输入
curl -H “host:base.example.com”-H “x-mse-tag:gray”118.31.118.69/a
结果如图在灰度环境中进行流转
场景三
第三个场景我们想要利用一些已有的请求信息来做灰度路由,对于x-user-id:100路由到灰度环境,其他在正式环境中流转。
在云原生网关上进行修改tag-gray,修改Header Key为x-user-id,值为100,创建成功后进行发布。
在代码上先访问正式环境,输入
curl -H “host:base.example.com”118.31.118.69/a
结果显示在正常环境中进行流转,再来用已有的用户标来做灰度路由,输入
curl -H “host:base.example.com”-H “x-user-id:100”118.31.118.69/a
结果显示在灰度环境中进行路由符合预期
场景四
在之前的场景中ABC都有灰度版本,现在只需要对AC进行灰度验证,B只有一个基建版本,我们期望流向带有x-user-id:100请求的链路经过云原生网关到A的灰度版本到B的基建版本再到C的灰度版本。其他链路请求在正常环境中进行流转。
因为之前已经部署过B的灰度版本,先来删掉,查看当前集群中的deployment,输入
k get deployment
结果显示如图
删掉B的灰度版本,输入
k delete deployment spring-cloud-b-new
删掉后查看状态,输入
k get pod
处于running状态,由于在之前的灰度版本中已经部署好所以不需要在云原生网关上再修改路由,只需要到终端上进行验证,输入
curl -H “host:base.example.com”-H “x-user-id:100”118.31.118.69/a
结果显示后端的正确流向是a的灰度,B的正式,然后C的灰度。a从灰度环境打向B的正式使用自动容灾,因为灰度环境中没有B的版本。
再来访问其他user-id,输入
curl-H“host:base.example.com”-H “x-user-id:101”118.31.118.69/a
结果显示全部在正式环境中