微服务核心理论 - 云基础场景下流量策略实现原理

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

1 微服务的基本流量策略

微服务提供了一些技术来实现对微服务的流量的管理,其中最典型的就是对流量进行拆分和转发。
具体体现在金丝雀发布(灰度发布)、ABTesting 以及流量染色 等策略方案上。

2 流量策略实现流控的本质

云原生基础场景下,如果想要实现流控和调度,需要具备以下几个条件:

  • 请求的流量中,需要附带某些特征,如流量的请求的Header、Cookies、queryParams等 中带有某些信息。
  • 部署在kubernetes上的服务(svc)的实例(pod),打上版本标签,如 label: default、label: version1、label:version2 等。
  • 在云原生基础组件(如 Service-Mesh平台)上对相关的服务配上策略:当请求的流量带有某些特征(如header中带有Dep=SO)时,流量路由到对应标签(如 version = version1 )的服务实例Pod上。
  • 不符合条件的路由则默认走到默认版本中(如 version = default)。

所以,流控调度的本质上是通过在流量中携带一些特征(如流量的请求的Header、Cookies、queryParams等),而Mesh会根据这些请求的特征进行路由匹配,转发到对应的带有某些特征的服务实例上。
未匹配成功的流量则走到默认版本或者给定的具体版本中,从而实现多个版本和跟默认版本的业务隔离的目标。这种模式下,实现 灰度发布、ABTesting 以及流量染色 都是很方便的。

3 流量染色流转的原理

这边以Istio 实现的 Service-Mesh为案例

3.1 Istio支持的策略模型

基于上述的策略模型,如果你想配置如下:请求的header 带有 username = brand 或者 departname = hr 的时候,将流量转发到服务的v1版本,否着转发到default版本。
则策略代码如下:

    # 说明:VirtualService 流量染色,根据不同的条件将流量发往不同特征的版本中,假设这边有default、v1、v2 版本
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: test-service1-vs
    spec:
      hosts:
      - test-service1  # 治理发往test-service1服务的流量
      exportTo:
      - "."
      http:  # 加各种路由条件,比如匹配人员、部门进行路由
      - match  # 用户匹配 brand,部门匹配 hr 部门时
        - headers:
            username:
              exact: brand
        - headers:
            departname:
              exact: hr
        route: 
          destination:
          # todo 匹配条件的流量路由到对应的服务上......
      - route: 
        - destination:
        # todo 不匹配条件的流量路由到对应的服务上......

3.2 Kubernetes中服务的部署模式

云原生基础平台上的服务遵循如下层级结构,namespace对标应用,svc对标服务。

假设你给你的服务配置了多个版本,比如你发布了default(默认版本)、v1版本。
检查kubernetes的信息会发现,service保持不变,这个命名为testsvc-admin-default的服务下,对应两个deployment,两个pod。

    root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get deployments
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    testsvc-admin-429mvh    1/1     1            1           18m
    testsvc-admin-default   1/1     1            1           142m
    root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get services
    NAME               TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE
    testsvc-admin-default   ClusterIP   172.100.110.220   <none>        80/TCP    142m
    root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get pods
    NAME                                READY   STATUS    RESTARTS   AGE
    testsvc-admin-429mvh-5b567969b4-nq4zp    2/2     Running   0          17m
    testsvc-admin-default-85467f8f79-xzfgz   2/2     Running   0          23m

看看两个deployment的信息对比,labels中的app属性一致,version属性不一致。所以,服务按照同一个app寻址,不同的version进行流量shift的方式进行。

    root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get deployment testsvc-admin-default  -o yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
        deployment.kubernetes.io/revision: "2"
      creationTimestamp: "2022-01-14T06:40:22Z"
      generation: 2
      labels:
        app: testsvc-admin-default
        appName: testsvc-admin
        appType: java
        projectName: testsvc-debug
        version: default
        workspaceName: SPACE_BASIC_SERVE  
      name: testsvc-admin-default
      namespace: testsvc-debug
      resourceVersion: "335716111"
      uid: 7531a9b3-53eb-475d-ae0b-75df957badb9
    
    root@xxxxxxxxxxxxxx:~# kubectl -n testsvc-debug get deployment testsvc-admin-429mvh  -o yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
        deployment.kubernetes.io/revision: "1"
      creationTimestamp: "2022-01-14T08:45:03Z"
      generation: 1
      labels:
        app: testsvc-admin-default
        appName: testsvc-admin
        appType: java
        projectName: testsvc-debug
        version: 429mvh
        workspaceName: SPACE_BASIC_SERVE
      name: testsvc-admin-429mvh
      namespace: testsvc-debug
      resourceVersion: "335719639"
      uid: 85c0e1f2-b56d-4afc-8c51-ccb887e420b6

现在,envoy的流转规则有了,服务的特征也有了,完整策略匹配代码如下:

    # 说明:VirtualService 流量染色,根据不同的条件将流量发往不同特征的版本中,假设这边有default、v1、v2 版本
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: test-svc-vs
    spec:
      hosts:
      - test-svc  # 治理发往test-svc服务的流量
      exportTo:
      - "."
      http:  # 加各种路由条件,比如匹配人员、部门进行路由
      - match  # 用户匹配 brand,部门匹配 hr 人事部时
        - headers:
            username:
              exact: brand
        - headers:
            departname:
              exact: hr
        route: 
          destination:
            host: test-svc
            subset: v1  # 匹配条件的流量路由到对应的服务的v1版本上
      - route: 
        - destination:
            host: test-svc  # 剩余的流量走到default版本上
            subset: default

3.3 流量的解析和流转

规则下发之后,envoy存储在本地,当流量出去的时候,outbound 那边会做一个判断。
如果是header中带上 username = brand 或者 departname = hr ,流量转发到带有v1 标签的pod中,
否则流量转发到带有default标签的pod中。

4 总结

丰富的流量管理策略为我们系统的稳定性,以及流量的多样化(金丝雀发布、ABTesting、分级扩散流量、流量染色)使用提供了保证。

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值