OpenSergo 流量路由:从场景到标准化的探索

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 流量路由,顾名思义就是将具有某些属性特征的流量,路由到指定的目标。流量路由是流量治理中重要的一环,多个路由如同流水线一样,形成一条路由链,从所有的地址表中筛选出最终目的地址集合,再通过负载均衡策略选择访问的地址。开发者可以基于流量路由标准来实现各种场景,如灰度发布、金丝雀发布、容灾路由、标签路由等。

观看直播回放:https://yqh.aliyun.com/live/detail/29692

微服务治理与 OpenSergo


随着微服务(MicroServices) 理念的兴起,让大规模、高并发、低延迟的分布式应用成为可能。但是微服务架构是一把双刃剑,随着微服务架构复杂化,在大规模之下,再小的问题都会牵一发而动全身,因此随着微服务架构增长,如果不对微服务进行恰当的治理,微服务架构带来的效率、稳定性问题很可能会远大于微服务本身带来的架构红利。可以说,现代微服务架构的四大件:服务提供者、服务消费者、注册配置中心,当然还有容易被大家忽视但又十分重要的一点,那就是微服务治理。微服务治理的使命就是对微服务体系中的各个组件与环节进行治理,可以说做好微服务治理那就是把微服务做稳做好的必不可少的一环。

在企业内部,往往存在着不同语言、不同通信协议的微服务,这种异构化的架构会导致治理微服务的过程中,业务开发者、架构师无法用统一的方式来对所有服务进行治理管控,并且这类异构会衍生出更多的痛点:

  • 业内对服务治理的能力和边界没有明确的认识,每个企业所定义的服务治理概念不一致,造成很高的理解和沟通成本。
  • 开源微服务框架众多,对于服务治理缺乏一些标准化的约定。例如,Spring Cloud 中定义的微服务接口和 Dubbo 中定义的接口就没有办法互通,通过 Dubbo 和 Istio 管理的微服务也没有办法进行统一治理。开发者无法通过统一的配置方式来对不同框架、不同语言的服务进行统一治理管控。
  • 缺少真正面向业务、能够减轻认知负担的抽象和标准。开发者真正想要的可能是简单的、指定服务间的调用关系和配置规则。但现在对于业务开发者来说,不仅需要了解不同微服务框架的部署架构,也要了解不同服务治理方式的概念和能力区别,认知成本很大。

基于上面这些痛点,阿里巴巴在2022年1月开始和 bilibili、CloudWego等厂商、社区讨论服务治理如何规范化和更加普及,从而共同发起了 OpenSergo 项目。

OpenSergo 是开放通用的,覆盖微服务及上下游关联组件的微服务治理项目,从微服务的角度出发,涵盖流量治理、服务容错、服务元信息治理、安全治理等关键治理领域,提供一系列的治理能力与标准、生态适配与最佳实践,支持 Java, Go, Rust 等多语言生态。OpenSergo 的最大特点就是以统一的一套配置/DSL/协议定义服务治理规则,面向多语言异构化架构,做到全链路生态覆盖。对于开发者来说可以通过同一套 OpenSergo CRD 标准配置针对微服务架构涉及到的每一个组件进行统一的治理管控,而无需关注各框架、语言的差异点,降低异构化、全链路服务治理管控的复杂度。

下面我们将从流量路由这个场景入手,从常见的微服务治理场景出发。先是根据流量路由的实践设计流量路由的 Spec,同时在 Spring Cloud Alibaba 中实践遵循 OpenSergo 标准的流量路由能力。


流量路由


流量路由,顾名思义就是将具有某些属性特征的流量,路由到指定的目标。流量路由是流量治理中重要的一环,我们可以基于流量路由标准来实现各种场景,如全链路灰度、标签路由、金丝雀发布等。


标签路由

标签路由是按照标签为维度对目标负载进行划分,符合条件的流量匹配至对应的目标,从而实现标签路由的能力。当然基于标签路由的能力,赋予标签各种含义我们就可以实现各种流量路由的场景化能力。

image.png



金丝雀发布

金丝雀发布是一种降低在生产中引入新软件版本的风险的技术,方法是在将更改推广到整个基础架构并使其可供所有人使用之前,缓慢地将更改推广到一小部分用户。金丝雀发布是一种在黑与白之间,能够平滑过渡的一种发布方式。让一部分用户继续用旧版本,一部分用户开始用新版本,如果用户对新版本没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到新版本上面来。一直都有听说,安全生产三板斧的概念:可灰度、可观测、可回滚。那么灰度发布能力就是帮助企业软件做到快速迭代验证的必备能力。

在K8s中金丝雀发布的最佳实践如下:第一步:新建灰度 Deployment,部署新版本的镜像,打上新版本的标签。第二步:配置针对新版本的标签路由规则。第三步:验证成功,扩大灰度比例。第四步:若验证成功,将稳定版本的应用更新成最新镜像;若验证失败,把灰度的 Deployment 副本数调整到 0 或删除该 Deployment。


全链路灰度

全链路灰度发布就是通过线上多个应用部署灰度版本,灰度流量全部进入灰度版本,正常流量进入生产版本。灰度版本只针对灰度流量验证,有效减少风险。我们可以通过流量路由结合流量染色可以实现全链路的流量灰度能力。

image.png


流量路由标准化


业界微服务治理存在概念不统一、配置形式不统一、能力不统一、多框架统一管控较为复杂等问题。比如我们希望实现流量路由的能力,在 Spring Cloud 中可能需要通过 Spring Cloud 动态规则的方式进行配置,在 istio 中可能又是另一套配置方式,在其它组件上可能又是不同的配置。不同框架治理配置方式的不一致使得微服务统一治理管控的复杂度相当高。为此我们需要通过OpenSergo实现一套标准化的流量路由能力与实践,这样在任 OpenSergo生态中的组件上需通过配置 OpenSergo TrafficRouter 规则,即可实现一致的流量路由能力。

image.png


我们在实践了许多流量路由的场景后,将流量路由规则进行了如下的设计与抽象。

OpenSergo 的流量路由规则 (v1alpha1) 主要分为如下:

  • Workload 集合的抽象 (VirtualWorkloads):将某一组 VirtualWorkload(如 Kubernetes Deployment, Statefulset 或者一组 pod,或某个 JVM 进程,甚至是一组 DB 实例)按照一定的特征进行分类。
  • 流量标签规则 (RouterRule):将特定特征的流量映射至特定特征所对应的 VirtualWorkloads 上。
  • 路由链规则(RouterChain)将特定的 RouterRuleVirtualWorkloads按照一定逻辑排列组合成 pipeline。


Workload 集合的抽象 (VirtualWorkloads)

VirtualWorkloads 虚拟工作负载集合的抽象即 VirtualWorkload 集合,其中会将 VirtualWorkload 按照一定的特征进行分类。

VirtualWorkload虚拟工作负载即 workload 集合的抽象,将一定属性特征的 workload 集合划分成一个 VirtualWorkload,其中 VirtualWorkload 可以是目标 service 集合也可以是 deployment,甚至可以是 database 的实例、库、表集合。

对于通用的 workload 场景,我们可以利用 VirtualWorkloads CRD 进行描述。特别地,对于 Kubernetes workload,我们可以通过直接在 workload 上打 label 的方式进行特征标记,如在 Deployment 上打上 traffic.opensergo.io/label: gray 标签代表当前 Deployment 的标签特征为 gray。

一个标准的 workloads 描述应该类似于:

apiVersion: traffic.opensergo.io/v1alpha1
kind: VirtualWorkloads
metadata:
  name: tag-rule
spec:
  selector:
    app: my-app
  virtualWorkload:
    - name: my-app-gray
      target: my-app-gray-deployment    
      type: deployment
      selector:
        tag: gray


流量路由规则 (RouterRule)

流量路由规则 (RouterRule) 将特定特征的流量映射至特定特征所对应的 VirtualWorkloads 上。


假设现在需要将内部测试用户灰度到新版主页,测试用户 uid=12345,UID 位于 X-User-Id header 中,不符合条件的外部用户流量访问原版主页。那么只需要配置如下 CRD 即可:

apiVersion: traffic.opensergo.io/v1alpha1
kind: RouterRule
metadata:
  name: tag-traffic-router-rule
spec:
  selector:
    app: my-app
  http: 
    - name: my-traffic-router-http-rule
      rule:  
        match:
          header: 
            X-User-Id:   # 参数名
              exact: 12345       # 参数值
          uri:
            exact: "/index"
        targets:
          - workloads: my-app-worksloads
            name: gray
      target:
        workloads: my-app-worksloads
        name: base

通过上述配置,我们可以将 path 为 /index,且 uid header 为 12345 的 HTTP 流量为灰度流量,访问灰度版本的新版主页。


标签路由场景的流量路由配置

假设我们希望 Header x-user-id为123的流量访问 spring-cloud-a 的具备 gray 标签的实例。其中 spring-cloud-a 的标签情况如下:

image.png


那么我们需要配置对应的 TrafficRouterRule 配置如下:

apiVersion: traffic.opensergo.io/v1alpha1
kind: TrafficRouterRule
metadata:
  name: tag-traffic-router-rule
spec:
  selector:
    app: spring-cloud-a
  http: 
    - name: my-traffic-router-http-rule
      rule:  
        match:
          headers: 
            X-User-Id:   # 参数名
              regex: "^(?!(?:\d{1,2}|100)$)[0-9]\d+$"       # 参数值
          queryParams:
            name:
              exact: xiaoming
          uri:
            prefix: "/"
        targets:
          - workloads: spring-cloud-a-worksloads
            name: gray
      target:
        - workloads: spring-cloud-a-worksloads
          name: base


对应的 VirtualWorkloads 配置如下:

apiVersion: traffic.opensergo.io/v1alpha1
kind: VirtualWorkloads
metadata:
  name: spring-cloud-a-worksloads
spec:
  selector:
    app: spring-cloud-a
  virtualWorkload:
    - name: gray
      target: spring-cloud-a
      type: deployment
      selector:
        tag: gray
      loadbalance: random
    - name: base
      target: spring-cloud-a
      type: deployment
      selector:
        tag: _base
      loadbalance: random


金丝雀发布场景的流量路由配置

我们配置了如下的金丝雀规则,希望 10% 的流量访问spring-cloud-a中具有 gray 标签的实例

image.png


对应的 TrafficRouterRule 配置如下:

apiVersion: traffic.opensergo.io/v1alpha1
kind: TrafficRouterRule
metadata:
  name: tag-traffic-router-rule
spec:
  selector:
    app: spring-cloud-a
  http: 
    - name: my-traffic-router-http-rule
      rule:
        targets:
          - workloads: spring-cloud-a-worksloads
            name: gray
            weight: 10
          - workloads: spring-cloud-a-worksloads
            name: base
            weight: 90
      target:
        - workloads: spring-cloud-a-worksloads
          name: base


流量路由 Demo 演示


image.png


  • Spring Cloud Alibaba Consumer 应用中增加 OpenSergo 的依赖,并启动Spring Cloud Alibaba流量路由的Demo
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>opensergo-resource-transform</artifactId>
    <version>2.2.9-SNAPSHOT</version>
</dependency>


配置OpenSergo流量路由

  • 启动 OpenSergo 控制面
  • 下发 TrafficRouterRule CRD规则

假设现在需要将灰度流量路由到v2版本,灰度请求符合如下条件 header:name=xiaoming,Params:location=shenzhen的请求流量去往灰度 v2 版本,不符合条件的流量访问v1版本。那么只需要配置如下 CRD 即可

apiVersion: fault-tolerance.opensergo.io/v1alpha1
kind: TrafficRouterRule
metadata:
  name: http-foo-rule
  labels:
    app: foo-app
spec:
  http:
    match:
      headers:
        name: 'xiaoming'
      queryParams:
        location: 'shenzhen'
    targets:
      - name: "v2"
        selectors:
          version: "v2"
  target:
    name: "v1"
    selectors:
      version: "v1"


结果验证

当我们执行 curl  http://127.0.0.1:18083/router-test

NacosRegistration{nacosDiscoveryProperties=NacosDiscoveryProperties{serverAddr='127.0.0.1:8848', endpoint='', namespace='', watchDelay=30000, logName='', service='service-provider', weight=1.0, clusterName='DEFAULT', group='DEFAULT_GROUP', namingLoadCacheAtStart='false', metadata={preserved.register.source=SPRING_CLOUD, version=v1}, registerEnabled=true, ip='192.168.1.4', networkInterface='', port=18082, secure=false, accessKey='', secretKey='', heartBeatInterval=null, heartBeatTimeout=null, ipDeleteTimeout=null, failFast=true}}

其中返回默认v1版本的实例

当我们执行curl -H 'name:xiaoming' http://127.0.0.1:18083/router-test\?location\=shenzhen

NacosRegistration{nacosDiscoveryProperties=NacosDiscoveryProperties{serverAddr='127.0.0.1:8848', endpoint='', namespace='', watchDelay=30000, logName='', service='service-provider', weight=1.0, clusterName='DEFAULT', group='DEFAULT_GROUP', namingLoadCacheAtStart='false', metadata={preserved.register.source=SPRING_CLOUD, version=v2}, registerEnabled=true, ip='192.168.1.4', networkInterface='', port=18081, secure=false, accessKey='', secretKey='', heartBeatInterval=null, heartBeatTimeout=null, ipDeleteTimeout=null, failFast=true}}

其中符合流量匹配的条件,返回默认v2版本的实例。


总结与展望


流量路由是微服务流量治理中的重要的一环,当然 MSE 还提供更广范围、更多场景的微服务治理能力,包括全链路灰度、无损上下线、微服务数据库治理、日志治理等一系列的微服务治理能力。服务治理是微服务改造深入到一定阶段之后的必经之路,是将微服务做稳做好的关键。同时我们也在与 CloudWeGo、Kratos、Spring Cloud Alibaba、Dubbo、ShardingSphere 等社区共同建设 OpenSergo 微服务治理标准,将企业与社区中微服务治理的场景与最佳实践共同提取成标准规范,也欢迎更多社区与企业一起参与 OpenSergo 微服务治理标准的共建。欢迎大家加入 OpenSergo 社区交流群(钉钉群)进行讨论:34826335

image.png

相关文章
|
6月前
|
Cloud Native 容器 Kubernetes
基于阿里云服务网格流量泳道的全链路流量管理(三):无侵入式的宽松模式泳道
本文简要讨论了使用流量泳道来实现全链路流量灰度管理的场景与方案,并回顾了阿里云服务网格 ASM 提供的严格与宽松两种模式的流量泳道、以及这两种模式各自的优势与挑战。接下来介绍了一种基于 OpenTelemetry 社区提出的 baggage 透传能力实现的无侵入式的宽松模式泳道,这种类型的流量泳道同时具有对业务代码侵入性低、同时保持宽松模式的灵活特性的特点。同时,我们还介绍了新的基于权重的流量引流策略,这种策略可以基于统一的流量匹配规则,将匹配到的流量以设定好的比例分发到不同的流量泳道。
73534 16
基于阿里云服务网格流量泳道的全链路流量管理(三):无侵入式的宽松模式泳道
|
运维 负载均衡 监控
服务网格下的东西向与南北向流量管理实践|学习笔记
快速学习服务网格下的东西向与南北向流量管理实践
1450 0
服务网格下的东西向与南北向流量管理实践|学习笔记
|
数据采集 缓存 监控
百亿流量微服务网关的设计与实现(6)
百亿流量微服务网关的设计与实现(6)
440 0
百亿流量微服务网关的设计与实现(6)
|
7月前
|
Java Go 数据库
OpenSergo/MSE & CloudWeGo 共同保障微服务运行时流量稳定性
微服务运行时稳定性的问题微服务的稳定性一直是开发者非常关注的话题。随着业务从单体架构向分布式架构演进以及部署方式的变化,服务之间的依赖关系变得越来越复杂,业务系统也面临着巨大的高可用挑战。大家可能都经历过以下的场景:演唱会抢票瞬间洪峰流量导致系统超出最大负载,load 飙高,用户无法正常下单;在线选...
169 0
OpenSergo/MSE & CloudWeGo 共同保障微服务运行时流量稳定性
|
运维 Prometheus Kubernetes
服务网格下的东西向与南北向流量管理实践|学习笔记(一)
快速学习服务网格下的东西向与南北向流量管理实践
服务网格下的东西向与南北向流量管理实践|学习笔记(一)
|
缓存 Dubbo Java
OpenSergo 即将发布 v1alpha1,丰富全链路异构架构的服务治理能力
OpenSergo 标准到底是什么样子的呢?我们可以利用 OpenSergo 标准来做哪些事情呢?下面我们来结合几个例子来进行介绍。
431 6
OpenSergo 即将发布 v1alpha1,丰富全链路异构架构的服务治理能力
|
存储 SQL 负载均衡
流量路由技术解析
Sentinel2.0 将基于 OpenSergo 流量路由规则实现基本的流量路由能力,支持多种流量路由策略、负载均衡策略、虚拟工作负载等。Sentinel2.0 期望支持 Http、RPC、SQL等微服务各种流量的路由能力,并且可以快速被各主流微服务框架所集成。
流量路由技术解析
|
数据可视化 容灾 Java
基于 Mesh 的统一路由在海外业务的实践
本文主要介绍我们最近在利用 Service Mesh 架构解决海外业务问题中一些实践和价值探索。我们在海外业务引入 Mesh 架构过程中,充分利用 Istio 的基于 yaml 来描述和定义路由的抽象能力,制定了企业流量治理标准,并将集团海外业务发展多年的多种路由模块统一成使用 Mesh 的统一路由框架,且在今年双十一支撑了全量的海外业务。也希望通过我们的经验介绍,可以给其他还在探索如何落地 Mesh 的同仁一些参考。
304 9
基于 Mesh 的统一路由在海外业务的实践
|
Kubernetes Cloud Native 前端开发
构建基于 Ingress 的全链路灰度能力
微服务架构下,有一些需求开发,涉及到微服务调用链路上的多个微服务同时发生了改动,通常每个微服务都会有灰度环境或分组来接受灰度流量,我们希望通过进入上游灰度环境的流量,也能进入下游灰度的环境中,确保1个请求始终在灰度环境中传递,即使这个调用链路上有一些微服务没有灰度环境,这些应用请求下游的时候依然能够回到灰度环境中。通过 MSE 提供的全链路灰度能力,可以在不需要修改任何您的业务代码的情况下,能够轻松实现上述能力。
构建基于 Ingress 的全链路灰度能力
|
负载均衡 Kubernetes API
服务网格下的东西向与南北向流量管理实践|学习笔记(三)
快速学习服务网格下的东西向与南北向流量管理实践
服务网格下的东西向与南北向流量管理实践|学习笔记(三)