Dubbo是一个开源分布式框架,致力于提供高性能和透明化的远程服务调用方案。遵循Dubbo框架的服务即为Dubbo服务。本文介绍如何配置Dubbo服务的DestinationRule和VirtualService,实现Dubbo服务流量管理。

前提条件

配置目标规则

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: demoservice
  namespace: default
spec:
  host: providers:com.alibaba.edas.DemoService0:1.0.0:test.DEFAULT-GROUP.public.nacos
  subsets:
  - name: v1
    labels:
      appversion: v1
  - name: v2
    labels:
      appversion: v2
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
配置Dubbo服务的目标规则需要重点注意以下3个字段:
  • simple:支持ROUND_ROBIN、LEAST_CONN、RANDOM 3种负载均衡策略。
    • ROUND_ROBIN:请求以轮询的方式转给实例。
    • LEAST_CONN:请求被转给最小连接数的实例。
    • RANDOM:请求以随机的方式转给实例。
  • labellabels标签都需要是来自于Nacos注册中心下的标签元信息。
    ACK集群下针对该Dubbo服务的标签元信息不会被采纳,这是因为Istiod当前只同步了Nacos注册中心下的标签元信息,忽略了Kubernetes该服务部署的Pod下的标签元信息。
    说明 Dubbo标签元信息注册到注册中心有以下两种方式:
    • 代码方式
      Map<String, String> params = service.getParameters();
      params.put("appversion", "v1");
    • 环境变量方式
      部署Deployment时添加环境变量 ,需要Dubbo版本2.7以上。
      dubbo.application.parameters=[{key1:value1},{key2:value2}]
    服务元信息对应Nacos注册中心服务详情页下的元数据部分,如下图所示。元数据
  • host:host标明了Dubbo服务,在服务注册中心具有唯一性。分为以下4个部分:
    1. providers:com.alibaba.edas.DemoService0:1.0.0:test:服务名,固定加上providers:前缀,后面由Dubbo服务的三要素interface:version:group构成。
    2. DEFAULT-GROUP:服务所在的分组名,默认为DEFAULT-GROUP
    3. public:服务注册所在的命名空间。
    4. nacos:Nacos注册中心的域名后缀.nacos

配置虚拟服务

配置Dubbo服务的虚拟服务需要重点注意以下3个字段:
说明 关于Dubbo服务的虚拟服务更多参数说明,请参见Dubbo服务的参数说明
  • services
    • 对应Dubbo服务接口名,支持prefix、exact、regex匹配。
    • services为数组类型,可以配置多个service,多个service之间为或关系,请求只需匹配其中一条即可。建议实际配置采用单个service方式。
  • routes
    • match
      • 可以根据方法名、参数个数、参数类型及取值来设置匹配。
      • 可以根据请求下的Header (attachements) 来设置匹配。
      • 数值匹配支持strValue、doubleValue、boolValue类型,具体匹配模式patterns支持prefix、exact、regex,可配置多条。
    • route

      指定了符合此条件的流量的实际目标地址,支持按照百分比权重设置流量流向。

配置示例1:根据请求参数指定服务流量

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demoservice0
spec:
  hosts:
  - providers:com.alibaba.edas.DemoService0
  dubbo:
  - routes:
    - match:
      ### genericService.$invoke(method, new String[]{String.class.getName()}, new Object[]{name})
      - method:
          argc: 3
          args:
          - index: 1
            strValue:
              patterns:
              - exact: sayHello
            type: java.lang.String
      route:
      - destination:
          subset: v1
        weight: 100
    - match:
      - method:
          argc: 3
          args:
          - index: 1
            strValue:
              patterns:
              - exact: sayWorld
            type: java.lang.String
      route:
      - destination:
          subset: v2
        weight: 100
    services:
    - prefix: providers:com.alibaba.edas.DemoService0
以上虚拟服务设置了以下限制:
  • 当请求中包含sayHello参数时,请求路由到v1版本的Dubbo服务。
  • 当请求中包含sayWorld参数时,请求路由到v2版本的Dubbo服务。

配置示例2:根据请求头指定服务流量

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demoservice0
spec:
  hosts:
  - providers:com.alibaba.edas.DemoService0
  dubbo:
  - routes:
    - match:
      - method:
          nameMatch:
            exact: "sayHello"
          argc: 1
          args:
          - index: 1
            strValue:
              patterns:
              - exact: "jack"
            type: java.lang.String
      route:
      - destination:
          subset: v1
        weight: 100
    - match:
      - method:
          nameMatch:
           exact: "sayHello"
          argc: 1
          args:
          - index: 1
            strValue:
              patterns:
              - exact: "lily"
            type: java.lang.String
       headers:
         app:
          patterns:
            - exact: "consumer1"
      route:
      - destination:
          subset: v2
        weight: 100
    services:
    - prefix: providers:com.alibaba.edas.DemoService0
以上虚拟服务配置的是针对providers:com.alibaba.edas.DemoService0服务的路由,设置了以下限制:
  • 所有sayHello("jack")请求会被路由到v1版本的Dubbo服务。
  • 只有来自consumer1的sayHello("lily")会被路由到v2版本的Dubbo服务。