opensergo/opensergo-specification

[Discussion] About add a customized match-action t for RouteRuleContext in RouterRule | 关于在 RouterRule 的 RouteRuleContext 中添加自定义流量匹配执行器的参数

jnan806 opened this issue · 7 comments

I'm not official member of community, here is my opinion.


(English version TBD...)


在 PR #29 中, 流量路由规范中通过 RouterRule 定义了多种协议的流量路由规则,每一种协议的路由规则中定义了**RequestMatch来提供给用户进行流量规则的定义。而我发现,在 HttpRequestMatchRpcRequestMatch中定义的几个内置参数,都是简单规则,都是可以通过我们手动定义的,如果遇到复杂的场景,无法提前预知参数或者无法手动定义复杂的规则的话,目前的设计就很难满足了。
因此,我提出一个想法:就是在**RouteRuleContext中,添加一个自定义匹配行为参数(暂命名为action),与match一样结果以truefalse来表示匹配成功与失败,但与match不同的是,action配置的是流量匹配执行器的工作负载。
通过这种方式,即使在opensergo中内置的流量匹配规则无法满足用户的需求的情况下,用户可自定义action并实现action对应的WorkLoad来满足自己复杂的路由规则。

  • 路由步骤:
  1. 如果存在match,则首先满足match
  2. 如果存在action,则在满足match的前提下,同时满足action

下面以http协议为例:

  • HttpRouteRuleContext
Field Type Description Required
name string No
match HttpRequestMatch Http流量的匹配规则 No
action HttpRequestAction Http流量的匹配执行器 No
targets VirtualWorkload[] 匹配到Http流量的匹配规则的目标虚拟工作负载集合 Yes
modify HttpModifyRule 对匹配到Http流量匹配规则的流量进行修改的规则 No
  • HttpRequestAction
Field Type Description Required
script string (oneof) 脚本 (同 PR #29StringMatchvars) No
workload VirtualWorkload (oneof) 工作负载 No
  • HttpRouteRule 流量路由规则
apiVersion: traffic.opensergo.io/v1alpha1
kind: RouterRule
metadata:
  name: my-traffic-router-rule
spec:
  selector:
    app: provider-app
  http: # http/rpc/db/redis
    - name: my-traffic-router-http-rule
      rule:
        match:
          headers: 
            - X-User-Id:   # 参数名
              exact: 12345       # 参数值
          uri:
            exact: "/index"
        action: 
           workload:
              workloads: my-request-rule-action
              name: http-action
      - target:
        - workloads: tag-rule
          name: my-app-gray
    target:
      - workloads: tag-rule
        name: my-app-base
  • HttpRouteRuleContext 中 action 的 VirtualWorkload 工作负载
apiVersion: traffic.opensergo.io/v1alpha1
kind: VirtualWorkloads
metadata:
  name: my-request-rule-action
spec:
  selector:
    app: rule-action
  virtualWorkload:
    - name: http-action
      target: http-action-container
      type: deployment
      selector:
        tag: http-action
      loadbalance: random
    - name: rpc-action
      target: rpc-action-container
      type: deployment
      selector:
        tag: rpc-action
      loadbalance: random
DC-ET commented

非社区官方人员,表达一下自己的看法。。

你的想法是流量路由规则在额外的工作负载中进行计算吧,我理解这样做会很影响请求的性能,尤其是在高并发的情况下,且自定义路由工作负载的稳定性会成为一个风险点。

我认为复杂的逻辑不应该放在路由规则这边,如果是复杂的打标逻辑,业务可以自己进行计算并在请求发起时携带自定义header,主动配合路由规则。

最后,在实际流量治理中,我是没遇到过特别复杂的路由规则,不知你遇到的复杂场景具体是什么样的场景,可以分享下,嘿嘿

DC-ET commented

关于匹配规则,目前我这边使用到的几种模式

  • 等于
  • 不等于
  • 前缀匹配
  • 后缀匹配
  • 包含
  • 正则匹配

其他能想到的可以扩展的模式的话,可以考虑比较运算,比如

  • 大于
  • 大等
  • 小于
  • 小等
  • 整除
  • 非整除
  • ...

(同非官方 😄 )

  • 场景1:
    涉密或涉敏参数作为路由规则,放在 url、header、queryParams 等均不合适。如果进行加解密/编解码可以解决,但需要提供加解密/编解码算法
  • 场景2:
    如果需要将body报文通过业务逻辑算法后进行路由,那么通过简单的规则匹配以及脚本模式无法满足。当然这一层可以下沉到后端业务部分,但既然opensergo已经有路由功能,那么我觉得用户可能就不想要自己后端在加一层额外的路由层了。
  • 其他场景一时还没想到

关于性能问题,其实我也有想到。我的想法是

  1. 应建议用户尽量优先使用match模式,
  2. match模式无法满足需求时,采用action模式

毕竟action模式中,无论 script 执行脚本或是workload 工作负载都会影响性能,所以最终是改造应用适应match还是牺牲性能采用action,交由用户自身考量

DC-ET commented

我的想法是这样的,社区或许可以内置一些常见的报文解析能力例如JSON、XML,同时也具备可扩展的能力。

http:
  - name: my-traffic-router-http-rule
    rule:
      match:
        body: 
         - type: json                        #报文取值方式,可扩展
            field: user.idcard             #取值表达式,实现通常可以是jsonpath、xpath
            exact: 12345
         - type: xml
            field: user.idcard
            exact: 12345 
         - type: custom
            field: user.idcard
            exact: 12345

现状:一个系统中的报文格式通常是比较固定的,而业务上将路由要素放在报文中的特定位置,在header、query、method中是没有什么有价值信息可作为路由要素的,需要业务开发者将报文解析并提取相关路由要素传递给路由组件。
预期:业务开发者不需要关心是依据什么业务字段进行路由,对业务开发者来说只是发起一个普通的请求。

(同非官方)

不建议在路由里面对报文进行解析,这对性能会产生比较明显的损耗。不过基于元数据部分(HTTP Header 等)我觉得是可以的。前面 @DC-ET 提到的一些字符串匹配模式都有必要,不过算数运算会涉及到把字符串数据进行类型转换,可能不太合适。

DC-ET commented