Skip to content
chengyouling edited this page Feb 18, 2024 · 12 revisions

路由管理

在微服务存在多个版本、多个实例的情况下,需要管理服务之间的路由,达到无损升级、应用拨测等业务目的。 常见的路由管理场景包括灰度发布、蓝绿发布等。

为了更好的描述Spring Cloud Huawei的路由管理,假设用户的使用如下典型的微服务架构:

    Spring Cloud Gateway --> Consumer --> Provider

服务级路由管理规则

servicecomb:
  routeRule:
    Provider: |                              # 服务名
      - precedence: 2                        # 优先级,数字越大,优先级越高。
        match:                               # 请求匹配规则。0..N个,不配置表示匹配。
          headers:                           # header 匹配
            region:                          # 如果配置了多个 header,那么所有的 header 规则都必须和请求匹配
              exact: 'providerRegion'
              caseInsensitive: false         # 区分大小写
            type:         
              regex: gray_[a-z]+             # java 正则表达式匹配
              caseInsensitive: true          # 不区分大小写
        route:                               # 路由规则
          - weight: 20                       # 权重值
            tags:
              version: 1.0.0                 # 实例标记。满足标记条件的实例放到这一组。
          - weight: 80                       # 权重值
            tags:
              version: 2.0.0                 # 实例标记。满足标记条件的实例放到这一组。
      
      - precedence: 1
        route:
          - weight: 20
            tags:
              x-group: red
          - weight: 80
            tags:
              x-group: green

上述规则指定 Consumer 访问 Provider 的路由管理。当请求中包含 region 和 type 两个 header 的时候,将 80% 流量转发到 2.0.0 版本, 将 20% 流量转发到 1.0.0 版本。 当请求中不包含上述 header 的时候, 将 80% 的流量转发到实例 tag 为 green 的实例, 20% 的流量转发到 实例 tag 为 red 的实例。

注意:当规则里面不含match的header匹配规则时,表示匹配。

全局路由管理规则

servicecomb:
  globalRouteRule: |
    - precedence: 2                        # 优先级,数字越大,优先级越高。
      match:                               # 请求匹配规则。0..N个,不配置表示匹配。
        headers:                           # header 匹配
          region:                          # 如果配置了多个 header,那么所有的 header 规则都必须和请求匹配
            exact: 'providerRegion'
            caseInsensitive: false         # 区分大小写
          type:         
            regex: gray_[a-z]+             # java 正则表达式匹配
            caseInsensitive: true          # 不区分大小写
      route:                               # 路由规则
        - weight: 20                       # 权重值
          tags:
            version: 1.0.0                 # 实例标记。满足标记条件的实例放到这一组。
        - weight: 80                       # 权重值
          tags:
            version: 2.0.0                 # 实例标记。满足标记条件的实例放到这一组。

上述规则指定 Consumer 访问下游所有服务端的路由管理。当请求中包含 region 和 type 两个 header 的时候,将 80% 流量转发到 2.0.0 版本, 将 20% 流量转发到 1.0.0 版本。 当请求中不包含上述 header 的时候, 将 80% 的流量转发到实例 tag 为 green 的实例, 20% 的流量转发到 实例 tag 为 red 的实例。

注意:当规则里面不含match的header匹配规则时,表示匹配。

  • 功能支持版本

功能版本要求:1.11.1-2021.0.x/1.11.1-2022.0.x及以上版本。

多泳道标签路由支持fallback降级配置路由

  • 多泳道示意图

  • 路由规则
servicecomb:
  routeRule:
    ServiceB: |                              # 服务名
      - precedence: 1                        # 优先级,数字越大,优先级越高。
        match:                               # 请求匹配规则。0..N个,不配置表示匹配。
          headers:                           # header 匹配
            region:                          # 如果配置了多个 header,那么所有的 header 规则都必须和请求匹配
              exact: 'providerRegion'
              caseInsensitive: false         # 区分大小写
        route:                               # 路由规则
          - weight: 100                      # 权重值
            tags:
              version: 0.0.3                 # 实例标记。满足标记条件的实例放到这一组。
        fallback:                            # 当前precedence下降级匹配规则
          - weight: 100
            tags:
              version: 0.0.1                 # 基线版本实例

结合多泳道示意图,业务已正常运行有泳道base、泳道A两条灰度泳道,泳道B的ServiceA(version:0.0.3)完成部署,但ServiceB(version:0.0.3)未部署时,请求进入泳道B的ServiceA,根据路由设置规则无法匹配ServiceB(version:0.0.3)服务:

1、未配置fallback路由时:流量会均匀分布到泳道base、泳道A的ServiceB服务; 2、配置fallback路由规则时:流量会100%分布到泳道base的ServiceB服务。

  • 功能支持版本

功能版本要求:1.11.4-2021.0.x/1.11.4-2022.0.x及以上版本。

如何配置实例的 tags

默认包含 version 这 1 个 tag, 不需要定义。 其他tag可以通过配置项给微服务实例增加属性。

spring:
  cloud:
    servicecomb:
      instance:
        properties:
          x-group: red

路由上下文如何获取和传递

路由上下文指路由管理规则里面的请求header信息,它由当前RestTemplate或者Feign的请求头信息和请求上下文构成。

1.10.7 之后(含)的版本

默认情况从两个地方获取 header 信息进行匹配。

  • 客户端请求的所有header。比如RestTemplate、Feign传递的header信息。
  • 请求上下文。

如果需要将外部请求的 header 参数或者 query 参数也作为微服务内部灰度发布匹配使用的 header, 可以在接受用户请求的第一个微服务(比如微服务网关)将需要的信息设置到请求上下文中。 详细参考请求上下文的介绍。

spring:
  cloud:
    servicecomb:
      context:
        headerContextMapper:
          canary: canary

1.10.7 之前(不含)的版本

当外部请求进入系统的时候,请求的所有header会复制到路由上下文中,路由上下文会在调用链中以请求上下文的方式传递。当服务发起客户端请求的时候, 客户端请求中的header会添加到路由上下文中,同时请求上下文也会添加到路由上下文中。 因此,在匹配header的时候,会有三个地方获取header:

  • 客户端请求的所有header。比如RestTemplate、Feign传递的header信息。
  • 请求上下文。详细参考请求上下文的介绍。
  • 进入系统的请求的header。 比如用户通过浏览器请求Spring Cloud Gateway,Spring Cloud Gateway读取到的所有header。如果没有 Spring Cloud Gateway, 请求直接调用Consumer,那么就是Consumer读取到的所有header。
Clone this wiki locally