alibaba / higress

Cloud Native API Gateway | 云原生API网关
https://higress.io
Apache License 2.0
2.5k stars 407 forks source link

feat: cluster key rate limit enhancement #1036

Closed hanxiantao closed 2 weeks ago

hanxiantao commented 2 weeks ago

Ⅰ. Describe what this PR did

cluster key rate limit enhancement 1)add limit_type: limit_by_consumer、limit_by_cookie、limit_by_per_header、limit_by_per_param、limit_by_per_consumer、limit_by_per_cookie 2)support batch configuration of rate limiting rules

Ⅱ. Does this pull request fix one issue?

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

1)、limit_by_param和limit_by_per_param

wasmplugin.yam:

apiVersion: extensions.higress.io/v1alpha1
kind: WasmPlugin
metadata:
  name: test
  namespace: higress-system
spec:
  defaultConfig:
    rule_name: default_rule
    rule_items:
      - limit_by_param: apikey
        limit_keys:
          - key: 9a342114-ba8a-11ec-b1bf-00163e1250b5
            query_per_minute: 10
          - key: a6a6d7f2-ba8a-11ec-bec2-00163e1250b5
            query_per_hour: 100
      - limit_by_per_param: apikey
        limit_keys:
          # 正则表达式,匹配以a开头的所有字符串,每个apikey对应的请求10qds
          - key: "regexp:^a.*"
            query_per_second: 10
          # 正则表达式,匹配以b开头的所有字符串,每个apikey对应的请求100qd
          - key: "regexp:^b.*"
            query_per_minute: 100
          # 兜底用,匹配所有请求,每个apikey对应的请求1000qdh
          - key: "*"
            query_per_hour: 1000
    redis:
      service_name: redis.static
    show_limit_quota_header: true
  url: oci://registry.cn-hangzhou.aliyuncs.com/wasm-plugin/wasm-plugin:0.0.68
  imagePullSecret: aliyun

1)根据第一个apikey进行限流

一分钟内请求三次:

curl -kvv -X GET 'http://localhost:8082/test?apikey=9a342114-ba8a-11ec-b1bf-00163e1250b5' \
-H 'Host: www.test.com'

根据第一个apikey进行限流

响应头中x-ratelimit-limit为10(限制的总请求数),x-ratelimit-remaining为7(剩余还可以发送的请求数)

2)根据第二个apikey限流

请求三次:

curl -kvv -X GET 'http://localhost:8082/test?apikey=a6a6d7f2-ba8a-11ec-bec2-00163e1250b5' \
-H 'Host: www.test.com'

根据第二个apikey限流

Redis中的数据: 根据第二个apikey限流Redis中的数据

3)正则表达式以b开头的字符串

一分钟内请求三次:

curl -kvv -X GET 'http://localhost:8082/test?apikey=b123456' \
-H 'Host: www.test.com'

正则表达式以b开头的字符串

响应头中x-ratelimit-limit为100(限制的总请求数),x-ratelimit-remaining为97(剩余还可以发送的请求数)s

**4)***

请求四次:

curl -kvv -X GET 'http://localhost:8082/test?apikey=123456' \
-H 'Host: www.test.com'

All请求三次

Redis中的数据: All请求三次Redis中的数据

2)、limit_by_header和limit_by_per_header

wasmplugin.yam:

apiVersion: extensions.higress.io/v1alpha1
kind: WasmPlugin
metadata:
  name: test
  namespace: higress-system
spec:
  defaultConfig:
    rule_name: default_rule
    rule_items:
      - limit_by_header: x-ca-key
        limit_keys:
          - key: 102234
            query_per_minute: 10
          - key: 308239
            query_per_hour: 10
      - limit_by_per_header: x-ca-key
        limit_keys:
          # 正则表达式,匹配以a开头的所有字符串,每个apikey对应的请求10qds
          - key: "regexp:^a.*"
            query_per_second: 10
          # 正则表达式,匹配以b开头的所有字符串,每个apikey对应的请求100qd
          - key: "regexp:^b.*"
            query_per_minute: 100
          # 兜底用,匹配所有请求,每个apikey对应的请求1000qdh
          - key: "*"
            query_per_hour: 1000            
    redis:
      service_name: redis.static
    show_limit_quota_header: true  
  url: oci://registry.cn-hangzhou.aliyuncs.com/wasm-plugin/wasm-plugin:0.0.68
  imagePullSecret: aliyun

1)根据第一个请求头进行限流

一分钟内请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'x-ca-key: 102234' -H 'Host: www.test.com'

根据第一个请求头进行限流

响应头中x-ratelimit-limit为10(限制的总请求数),x-ratelimit-remaining为7(剩余还可以发送的请求数)

2)根据第二个请求头进行限流

请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'x-ca-key: 308239' -H 'Host: www.test.com'

根据第二个请求头进行限流

Redis中的数据:

根据第二个请求头进行限流Redis中的数据

3)正则表达式以b开头的字符串

一分钟内请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'x-ca-key: b123456' -H 'Host: www.test.com'

正则表达式以b开头的字符串

响应头中x-ratelimit-limit为100(限制的总请求数),x-ratelimit-remaining为97(剩余还可以发送的请求数)s

**4)***

请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'x-ca-key: 123456' -H 'Host: www.test.com'

All请求三次

Redis中的数据:

All请求三次Redis中的数据

3)、limit_by_cookie和limit_by_per_cookie

wasmplugin.yam:

apiVersion: extensions.higress.io/v1alpha1
kind: WasmPlugin
metadata:
  name: test
  namespace: higress-system
spec:
  defaultConfig:
    rule_name: default_rule
    rule_items:
      - limit_by_cookie: key1
        limit_keys:
          - key: value1
            query_per_minute: 10
          - key: value2
            query_per_hour: 100
      - limit_by_per_cookie: key1
        limit_keys:
          # 正则表达式,匹配以a开头的所有字符串,每个cookie中的value对应的请求10qds
          - key: "regexp:^a.*"
            query_per_second: 10
          # 正则表达式,匹配以b开头的所有字符串,每个cookie中的value对应的请求100qd
          - key: "regexp:^b.*"
            query_per_minute: 100
          # 兜底用,匹配所有请求,每个cookie中的value对应的请求1000qdh
          - key: "*"
            query_per_hour: 1000 
    rejected_code: 200
    rejected_msg: '{"code":-1,"msg":"Too many requests"}'
    redis:
      service_name: redis.static
    show_limit_quota_header: true  
  url: oci://registry.cn-hangzhou.aliyuncs.com/wasm-plugin/wasm-plugin:0.0.68
  imagePullSecret: aliyun

1)根据第一个cookie进行限流

一分钟内请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'Host: www.test.com' -H 'Cookie: test=www.test.com;key1=value1'

根据第一个cookie进行限流

响应头中x-ratelimit-limit为10(限制的总请求数),x-ratelimit-remaining为7(剩余还可以发送的请求数)

触发限流后:

根据第一个cookie进行限流触发限流后

2)根据第二个cookie限流

请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'Host: www.test.com' -H 'Cookie: test=www.test.com;key2=value1;key1=value2'

根据第二个cookie限流

Redis中的数据:

根据第二个cookie限流Redis中的数据

3)正则表达式以b开头的字符串

一分钟内请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'Host: www.test.com' -H 'Cookie: test=www.test.com;key2=value1;key1=bbbb'

正则表达式以b开头的字符串

响应头中x-ratelimit-limit为100(限制的总请求数),x-ratelimit-remaining为97(剩余还可以发送的请求数)

**4)***

请求三次:

curl -kvv -X GET 'http://localhost:8082/test' -H 'Host: www.test.com' -H 'Cookie: test=www.test.com;key2=value1;key1=helloworld'

All请求三次

Redis中的数据:

All请求三次Redis中的数据

4)、limit_by_per_ip

wasmplugin.yam:

apiVersion: extensions.higress.io/v1alpha1
kind: WasmPlugin
metadata:
  name: test
  namespace: higress-system
spec:
  defaultConfig:
    rule_name: default_rule
    rule_items:
      - limit_by_per_ip: from-header-x-forwarded-for
        limit_keys:
          # 精确ip
          - key: 1.1.1.1
            query_per_day: 10
          # ip段,符合这个ip段的ip,每个ip 100qpd
          - key: 1.1.1.0/24
            query_per_day: 100
          # 兜底用,即默认每个ip 1000qpd
          - key: 0.0.0.0/0
            query_per_day: 1000
    redis:
      service_name: redis.static
    show_limit_quota_header: true    
  url: oci://registry.cn-hangzhou.aliyuncs.com/wasm-plugin/wasm-plugin:0.0.68
  imagePullSecret: aliyun

1)1.1.1.1

连续请求三次:

curl -kvv -X GET 'http://localhost:8082/test' \
-H 'Host: www.test.com' \
-H 'x-forwarded-for: 1.1.1.1,2.1.1.1'

根据第一个ip进行限流

响应头中x-ratelimit-limit为10(限制的总请求数),x-ratelimit-remaining为7(剩余还可以发送的请求数)

2)1.1.1.0/24

请求三次:

curl -kvv -X GET 'http://localhost:8082/test' \
-H 'Host: www.test.com' \
-H 'x-forwarded-for: 1.1.1.2,2.1.1.1'

ip段请求三次

Redis中的数据: ip段请求三次Redis中数据

3)0.0.0.0/0

请求三次:

curl -kvv -X GET 'http://localhost:8082/test' \
-H 'Host: www.test.com' \
-H 'x-forwarded-for: 2.1.1.2,2.1.1.1'

all请求三次

Redis中的数据: all请求三次Redis中数据

4)、limit_by_consumer和limit_by_per_consumer Redis中key示例:

image

Ⅴ. Special notes for reviews