跳转至

集群间分流

概述

  • 在BFE的接入转发流程中,在确定产品线后,要进一步确定处理该请求的目标集群
  • BFE为每个产品线维护一张“转发表”
  • 对每个属于该产品线的请求,查询转发表,获得目标集群

转发表的组成

转发表包括2部分:

  • 基础规则表:由基础规则组成。使用域名(Host)和路径(Path)作为匹配条件,基础规则表中的规则按最长匹配原则进行匹配。
  • 高级规则表:由高级规则组成。使用请求中的多种信息(如host、path、header、cookie、method等)进行匹配,高级规则表中的规则按先后顺序进行顺序匹配。在高级规则表中可以设置默认规则。

基础规则表使用树形查找,匹配速度快,可以支持较大数量(几千甚至上万)转发规则的快速查找;高级规则表支持更强大的条件描述能力,但是在规则数量较多(超过100条)时会有明显的性能下降。

匹配顺序

BFE会按照基础规则表、高级规则表的顺序来查找,以确定目标集群。

在基础规则表中,也可以将某条规则的目标集群设置为“ADVANCED_MODE”(高级模式),命中此规则的请求将转至高级规则表进一步匹配。

详细的匹配顺序见下图。

route table

基础规则表

基础规则说明

基础规则表由多条“基础规则”组成。

  • 基础规则的匹配条件包括域名(host)和路径(path)两个部分。
  • 目的集群通过集群名称来指定,也可以设置为“ADVANCED_MODE”转至高级规则表继续匹配。

基础规则没有前后顺序关系,而是基于精确优先、最长匹配的原则。详细的匹配方式见后面的“基础规则匹配顺序”。

基础规则匹配条件

一条基础规则可以指定host条件或path条件,或者同时指定host条件和path条件。

host条件的描述语法遵循以下规则:

  • 以"."作为域名标签元素的分割符(域名标签元素指的是由 "."分隔的host中的标签。)
  • 支持“精确匹配”、“通配符匹配”和“任意匹配”
  • 精确匹配:完整的域名,如:www.test1.com
  • 通配符匹配:第一个域名标签元素为通配符"*"表示这个描述为通配符匹配。 "*"仅能出现一次,且仅可以表示一个域名标签元素,例如*.test.com。而*est.com和*.*.com均不符合语法。
  • 任意匹配:一种特殊的通配符匹配,可以填写单独的通配符"*"来表示匹配任意的host值(与通配符匹配不同,任意匹配的*可以匹配包含多个域名标签元素的host)
  • 一条规则的host条件,支持多个host描述,如:"www.test1.com", "*.example.com"

示例:

host描述 请求的host 是否匹配?
* www.test1.com 匹配
*.test1.com host.test1.com 匹配
*.test1.com vip.host.test1.com 不匹配,* 只匹配一个域名标签元素
*.test1.com example.com 不匹配
*.test1.com test1.com 不匹配

path条件的描述语法遵循以下规则:

  • 以"/"作为路径元素的分割符(路径元素指的是由 "/" 分隔符分隔的路径中的标签。)
  • 除了任意匹配,均以"/"开始
  • 支持“精确匹配”和“前缀匹配”
  • 精确匹配:完整的路径,如/path
  • 前缀匹配:在路径前缀后面使用"*"来表示这个描述为前缀匹配,即从左开始对path中的路径元素逐个匹配。 "*"仅能出现一次,且可以表示一个或多个连续的路径元素。前缀匹配的描述也可以是一个单独的"*"。举例如下:
    • /foo/bar 这个path,条件 /* 和 /foo/* 均能匹配到;
    • /foo/* 和 /foo* 是等价的;
    • /foo/bar 这个path,不能被条件 /foo/b* 匹配到;
    • /*/* 不符合path描述的语法
  • 一条规则的path条件,支持多个path描述,如:"/foo/bar", "/foo/cell/*"

更多示例:

path描述 请求的path 是否匹配
* 任何path值 匹配
/ 空值 不匹配
/ /a 不匹配
/* 空值 不匹配
/* / 匹配,*可以匹配空值
/* /a/ 匹配,忽略尾部斜线
/a/b/* (与 /a/b* 等价) /a/b/c 匹配
/a/b/* (与 /a/b* 等价) /a/b/c/d 匹配,*可以匹配多个路径元素
/a/b/* (与 /a/b* 等价) /a/b 匹配,忽略尾部斜线,*可以匹配空值
/a/b/* (与 /a/b* 等价) /a/c 不匹配
/a/b/* (与 /a/b* 等价) /a 不匹配
/a/b* /a/bacon 不匹配

基础规则匹配顺序

在基础规则表中查找时,先host条件匹配,符合host条件的规则,再进行path条件匹配:

  1. 首先对host进行精确匹配
  2. 对匹配到的规则(可能是一条或多条),再尝试匹配这些规则的path条件;
    • 若匹配path条件成功,即为命中规则;
    • 若匹配path条件未成功,则判定为未命中基础规则,转由高级规则进行匹配
  3. host精确匹配未成功的,对host进行通配符匹配
  4. 对匹配到的规则(可能是一条或多条),再尝试匹配这些规则的path条件;
    • 若匹配path条件成功,即为命中规则;
    • 若匹配path条件未成功,则判定为未命中基础规则,转由高级规则进行匹配
  5. host通配符匹配未成功的,对host进行任意匹配
  6. 对匹配到的规则(可能是一条或多条),再尝试匹配这些规则的path条件;
    • 若匹配path条件成功,即为命中规则;
    • 若匹配path条件未成功,则判定为未命中基础规则,转由高级规则进行匹配
  7. 基础规则匹配结束,未命中的,转由高级规则进行匹配

其中,对于上面步骤中,对host条件匹配到的规则,进行匹配path条件时的匹配逻辑如下:

  1. 首先对path进行精确匹配
  2. 精确匹配未成功的,对path进行前缀匹配。前缀匹配使用最长匹配原则,即若请求的path符合多条规则的path条件,匹配到从左开始有最多路径元素的那条规则(只会是一条规则)

基础规则匹配示例

有四条基础规则,分别为:

  • 规则1:host条件:*.test1.com,path条件:空值,目标集群:StaticCluster
  • 规则2:host条件:*.b.test1.com,path条件:/interface/* ,目标集群:PhpCluster
  • 规则3:host条件:*.b.test1.com, path条件:/*, 目标集群:StaticCluster
  • 规则4:host条件:www.test1.com, path条件:/interface/d, 目标集群:PhpCluster

收到一个请求,请求URL为vip.b.test1.com/interface/d

首先对host匹配:

1.host精确匹配,未匹配成功

2.host通配符匹配,发现请求的host(vip.b.test1.com)可以满足规则2,3的host条件(注意,规则1不匹配该请求,因为通配符"*"只能匹配一个域名标签元素)。

继续进行path匹配:

1.path精确匹配,未匹配成功

2.path前缀匹配,发现请求的path(/interface/d)可以满足规则2和规则3的path条件,根据最长匹配原则,匹配到从左开始有最多路径元素的那条规则,即规则2。

匹配结束,在基础规则表中命中规则2。根据规则2的设置,将请求转发到集群PhpCluster。

高级规则表

高级规则列表由多条有顺序的“高级规则”组成。

  • 高级规则的匹配条件使用了一个伪码描述机制“条件表达式”(Condition Expression,后面简称为Condition或条件表达式)来表述。
  • 目的集群通过集群名称来指定。

在查询时,对多条高级规则顺序查找:

  • 基于HTTP请求中的信息,根据转发规则的匹配条件进行条件判断,符合匹配条件的为命中该转发规则。可以使用的请求信息包括:host,path,query,cookie,method等
  • 只要命中任何一条转发规则,就会由此确定目的集群并结束退出。
  • 高级规则表中包含“默认规则(Default)。若所有转发规则都没有命中,将执行默认规则。

示例

  • 产品线demo,包含多种服务集群:Demo-A, Demo-B, Demo-C, Demo-D,Demo-E

  • 期望的集群间分流如下:

    • 对于host为www.a.com,且path为"/a/*" (除了"/a/b") 的请求,转发至Demo-A集群
    • 对于host为www.a.com,且path为"/a/b"的请求,转发至Demo-B集群
    • 对于其他host为*.a.com的请求,转发至Demo-C集群
    • 对于host为www.c.com的请求,转发至Demo-D集群
    • 针对Demo-D集群,另外开启了一个灰度集群Demo-D1。如果cookie中包含deviceid,且这个cookie的值以“x”开头,则转发至Demo-D1
    • 其它请求,都发往Demo-E
  • 对应以上要求,基础规则表的配置为:

host条件 path条件 目标集群
www.a.com /a/* Demo-A
www.a.com /a/b Demo-B
*.a.com * Demo-C
www.c.com * ADVANCED_MODE

在基础规则表中,规则之间没有前后顺序。见前面关于“基础规则匹配顺序”的说明。

针对Demo-D集群上应用的灰度发布,由于需要使用cookie中的信息,所以使用ADVANCED_MODE将满足条件的请求透传到高级规则表继续处理;在不需要灰度发布的时候,在基础规则表中www.c.com对应规则的目标集群写为Demo-D即可。

  • 高级规则表的配置为:
匹配条件 目标集群
req_host_in("www.c.com") && req_cookie_value_prefix_in("deviceid", "x", false) Demo-D1
req_host_in("www.c.com") Demo-D
default Demo-E

在高级规则表中,多条规则之间是有序的。需要将转发给Demo-D1的规则放在转发给Demo-D的规则的前面。

高级规则表中包含默认规则,对于没有命中其它规则的请求将被转发到Demo-E。

以上配置信息,对应的配置文件(/conf/server_data_conf/route_rule.conf)如下:

{
    "Version": "1.0",
    "BasicRule": {
        "demo": [
            {
                "Hostname": ["www.a.com"],
                "Path": ["/a/*"], 
                "ClusterName": "Demo-A"
            },
            {
                "Hostname": ["www.a.com"],
                "Path": ["/a/b"],
                "ClusterName": "Demo-B"
            },
            {
                "Hostname": ["*.a.com"],
                "Path": "*",
                "ClusterName": "Demo-C"
            },
            {
                "Hostname": ["www.c.com"],
                "Path": "*",
                "ClusterName": "ADVANCED_MODE"
            }
        ]
    },
    "ProductRule": {
        "demo": [
            {
                "Cond": " req_host_in(\"www.c.com\") && req_cookie_value_prefix_in(\"deviceid\", \"x\", false)",
                "ClusterName": "Demo-D1"
            },
            {
                "Cond": " req_host_in(\"www.c.com\")",
                "ClusterName": "Demo-D"
            },
            {
                "Cond": "default_t()",
                "ClusterName": "Demo-E"
            }
        ]
    }    
}