c语言sscanf函数的用法是什么
364
2022-11-05
基于 Istio 的全链路灰度方案探索和实
作者|曾宇星(宇曾)审核&校对:曾宇星(宇曾)编辑&排版:雯燕
背景
场景说明
实现原理
实现流量打标
ASM Pro 中引入了全新的 TrafficLabel CRD 用于定义 Sidecar 所需透传的流量标签从哪里获取。下面所例举的 YAML 文件中,定义了流量标签来源和需要将标签存储 OpenTracing 中(具体是 x-trace 头)。其中流量标的名为 trafficLabel,取值依次从 $getContext(x-request-id) 到最后从本地环境的$(localLabel)中获取。
apiVersion: istio.alibabacloud.com/v1beta1 kind: TrafficLabel metadata: name: default spec: rules: - labels: - name: trafficLabel valueFrom: - $getContext(x-request-id) //若使用aliyun arms,对应为x-b3-traceid - $(localLabel) attachTo: - opentracing # 表示生效的协议,空为都不生效,*为都生效 protocols: "*"
CR 定义包含两块,即标签的获取和存储。
获取逻辑:先根据协议上下文或者头(Header 部分)中的定义的字段获取流量标签,如果没有,会根据 traceId 通过 Sidecar 本地记录的 map 获取, 该 map 表中保存了 traceId 对应流量标识的映射。若 map 表中找到对应映射,会将该流量打上对应的流量标,若获取不到,会将流量标取值为本地部署对应环境的 localLabel。localLabel 对应本地部署的关联 label,label 名为 ASM_TRAFFIC_TAG。
存储逻辑:attachTo 指定存储在协议上下文的对应字段,比如 HTTP 对应 Header 字段,Dubbo 对应 rpc context 部分,具体存储到哪一个字段中可配置。
有了TrafficLabel 的定义,我们知道如何将流量打标和传递标签,但光有这个还不足以做到全链路灰度,我们还需要一个可以基于 trafficLabel 流量标识来做路由的功能,也就是“按标路由”,以及路由 fallback 等逻辑,以便当路由的目的地不存在时,可以实现降级的功能。
按流量标签路由
这一功能的实现扩展了 Istio 的 VirtualService 和 DestinationRule。
在 DestinationRule 中定义 Subset
自定义分组 subset 对应的是 trafficLabel 的 value
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: myapp spec: host: myapp/* subsets: - name: myproject # 项目环境 labels: env: abc - name: isolation # 隔离环境 labels: env: xxx # 机器分组 - name: testing-trunk # 主干环境 labels: env: yyy - name: testing # 日常环境 labels: env: zzz --- apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: myapp spec: hosts: - myapp/* ports: - number: 12200 name: http protocol: HTTP endpoints: - address: 0.0.0.0 labels: env: abc - address: 1.1.1.1 labels: env: xxx - address: 2.2.2.2 labels: env: zzz - address: 3.3.3.3 labels: env: yyy
Subset 支持两种指定形式:
labels 用于匹配应用中带特定标记的节点(endpoint); 通过 ServiceEntry 用于指定属于特定 subset 的 IP 地址,注意这种方式与labels指定逻辑不同,它们可以不是从注册中心(K8s 或者其他)拿到的地址,直接通过配置的方式指定。适用于 Mock 环境,这个环境下的节点并没有向服务注册中心注册。
在 VirtualService 中基于 subset
1)全局默认配置
route 部分可以按顺序指定多个 destination,多个 destination 之间按照 weight 值的比例来分配流量。 每个 destination 下可以指定 fallback 策略,case 标识在什么情况下执行 fallback,取值:noinstances(无服务资源)、noavailabled(有服务资源但是服务不可用),target 指定 fallback 的目标环境。如果不指定 fallback,则强制在该 destination 的环境下执行。 按标路由逻辑,我们通过改造 VirtualService,让 subset 支持占位符 $trafficLabel, 该占位符 $trafficLabel 表示从请求流量标中获取目标环境, 对应 TrafficLabel CR 中的定义。
全局默认模式对应泳道,也就是单个环境内封闭,同时指定了环境级别的 fallback 策略。自定义分组 subset 对应的是 trafficLabel 的 value 配置样例如下:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: default-route spec: hosts: # 对所有应用生效 - */* http: - name: default-route route: - destination: subset: $trafficLabel weight: 100 fallback: case: noinstances target: testing-trunk - destination: host: */* subset: testing-trunk # 主干环境 weight: 0 fallback: case: noavailabled target: testing - destination: subset: testing # 日常环境 weight: 0 fallback: case: noavailabled target: mock - destination: host: */* subset: mock # Mock中心 weight: 0
2)个人开发环境定制
先打到日常环境,当日常环境没有服务资源时,再打到主干环境。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: projectx-route spec: hosts: # 只对myapp生效 - myapp/* http: - name: dev-x-route match: trafficLabel: - exact: dev-x # dev环境: x route: - destination: host: myapp/* subset: testing # 日常环境 weight: 100 fallback: case: noinstances target: testing-trunk - destination: host: myapp/* subset: testing-trunk # 主干环境 weight: 0
3) 支持权重配置
将打了主干环境标并且本机环境是 dev-x 的流量,80% 打到主干环境,20% 打到日常环境。当主干环境没有可用的服务资源时,流量打到日常。 sourceLabels 为本地 workload 对应的 label
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: dev-x-route spec: hosts: # 对哪些应用生效(不支持多应用配置) - myapp/* http: - name: dev-x-route match: trafficLabel: - exact: testing-trunk # 主干环境标 sourceLabels: - exact: dev-x # 流量来自某个项目环境 route: - destination: host: myapp/* subset: testing-trunk # 80%流量打向主干环境 weight: 80 fallback: case: noavailabled target: testing - destination: host: myapp/* subset: testing # 20%流量打向日常环境 weight: 20
按(环境)标路由
该方案依赖业务部署应用时带上相关标识(例子中对应 label 为 ASM_TRAFFIC_TAG: xxx),常见为环境标识,标识可以理解是服务部署的相关元信息,这个依赖上游部署系统 CI/CD 系统的串联,大概示意图如下:
基于“流量打标” 和 “按标路由”能力还可以用于其他相关场景:
大促前的性能压测。在线上压测的场景中,为了让压测数据和正式的线上数据实现隔离,常用的方法是对于消息队列,缓存,数据库使用影子的方式。这就需要流量打标的技术,通过 tag 区分请求是测试流量还是生产流量。当然,这需要 Sidecar 对中间件比如 Redis、RocketMQ 等进行支持。 单元化路由。常见的单元化路由场景,可能是需要根据请求流量中的某些元信息比如 uid,然后通过配置得出对应所属的单元。在这个场景中,我们可以通过扩展 TrafficLabel 定义获取“单元标”的函数来给流量打上“单元标”,然后基于“单元标”将流量路由到对应的服务单元。 相关链接: 1)阿里云 ASM Pro:https://servicemesh.console.aliyun.com/
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~