|
1 | 1 | # 功能说明
|
2 | 2 |
|
3 |
| -`key-cluster-rate-limit`插件实现了基于特定键值实现集群限流,键值来源可以是 URL 参数、HTTP 请求头、客户端 IP 地址 |
| 3 | +`key-cluster-rate-limit`插件实现了基于特定键值实现集群限流,键值来源可以是 URL 参数、HTTP 请求头、客户端 IP 地址、consumer 名称、cookie中 key 名称 |
4 | 4 |
|
5 | 5 |
|
6 | 6 |
|
7 | 7 | # 配置说明
|
8 | 8 |
|
9 |
| -| 配置项 | 类型 | 必填 | 默认值 | 说明 | |
10 |
| -| ----------------------- | ------ | ---- | ------ | ---- | |
11 |
| -| rule_name | string | 是 | - | 限流规则名称,根据限流规则名称和限流的客户端IP段来拼装redis key | |
12 |
| -| limit_by_header | string | 否,`limit_by_header`,`limit_by_param`,`limit_by_per_ip` 中选填一项 | - | 配置获取限流键值的来源 http 请求头名称 | |
13 |
| -| limit_by_param | string | 否,`limit_by_header`,`limit_by_param`,`limit_by_per_ip` 中选填一项 | - | 配置获取限流键值的来源 URL 参数名称 | |
14 |
| -| limit_by_per_ip | string | 否,`limit_by_header`,`limit_by_param`,`limit_by_per_ip` 中选填一项 | - | 配置获取限流键值的来源 IP 参数名称,从请求头获取,以`from-header-对应的header名`,示例:`from-header-x-forwarded-for`,直接获取对端socket ip,配置为`from-remote-addr` | |
15 |
| -| limit_keys | array of object | 是 | - | 配置匹配键值后的限流次数 | |
| 9 | +| 配置项 | 类型 | 必填 | 默认值 | 说明 | |
| 10 | +| ----------------------- | ------ | ---- | ------ |---------------------------------------------------------------------------| |
| 11 | +| rule_name | string | 是 | - | 限流规则名称,根据限流规则名称+限流类型+限流key名称+限流key对应的实际值来拼装redis key | |
| 12 | +| rule_items | array of object | 是 | - | 限流规则项,按照rule_items下的排列顺序,匹配第一个rule_item后命中限流规则,后续规则将被忽略 | |
16 | 13 | | show_limit_quota_header | bool | 否 | false | 响应头中是否显示`X-RateLimit-Limit`(限制的总请求数)和`X-RateLimit-Remaining`(剩余还可以发送的请求数) |
|
17 |
| -| rejected_code | int | 否 | 429 | 请求被限流时,返回的HTTP状态码 | |
18 |
| -| rejected_msg | string | 否 | Too many requests | 请求被限流时,返回的响应体 | |
19 |
| -| redis | object | 是 | - | redis相关配置 | |
| 14 | +| rejected_code | int | 否 | 429 | 请求被限流时,返回的HTTP状态码 | |
| 15 | +| rejected_msg | string | 否 | Too many requests | 请求被限流时,返回的响应体 | |
| 16 | +| redis | object | 是 | - | redis相关配置 | |
| 17 | + |
| 18 | +`rule_items`中每一项的配置字段说明 |
| 19 | + |
| 20 | +| 配置项 | 类型 | 必填 | 默认值 | 说明 | |
| 21 | +| --------------------- | --------------- | -------------------------- | ------ | ------------------------------------------------------------ | |
| 22 | +| limit_by_header | string | 否,`limit_by_*`中选填一项 | - | 配置获取限流键值的来源 HTTP 请求头名称 | |
| 23 | +| limit_by_param | string | 否,`limit_by_*`中选填一项 | - | 配置获取限流键值的来源 URL 参数名称 | |
| 24 | +| limit_by_consumer | string | 否,`limit_by_*`中选填一项 | - | 根据 consumer 名称进行限流,无需添加实际值 | |
| 25 | +| limit_by_cookie | string | 否,`limit_by_*`中选填一项 | - | 配置获取限流键值的来源 Cookie中 key 名称 | |
| 26 | +| limit_by_per_header | string | 否,`limit_by_*`中选填一项 | - | 按规则匹配特定 HTTP 请求头,并对每个请求头分别计算限流,配置获取限流键值的来源 HTTP 请求头名称,配置`limit_keys`时支持正则表达式或`*` | |
| 27 | +| limit_by_per_param | string | 否,`limit_by_*`中选填一项 | - | 按规则匹配特定 URL 参数,并对每个参数分别计算限流,配置获取限流键值的来源 URL 参数名称,配置`limit_keys`时支持正则表达式或`*` | |
| 28 | +| limit_by_per_consumer | string | 否,`limit_by_*`中选填一项 | - | 按规则匹配特定 consumer,并对每个 consumer 分别计算限流,根据 consumer 名称进行限流,无需添加实际值,配置`limit_keys`时支持正则表达式或`*` | |
| 29 | +| limit_by_per_cookie | string | 否,`limit_by_*`中选填一项 | - | 按规则匹配特定 Cookie,并对每个 Cookie 分别计算限流,配置获取限流键值的来源 Cookie中 key 名称,配置`limit_keys`时支持正则表达式或`*` | |
| 30 | +| limit_by_per_ip | string | 否,`limit_by_*`中选填一项 | - | 按规则匹配特定 IP,并对每个 IP 分别计算限流,配置获取限流键值的来源 IP 参数名称,从请求头获取,以`from-header-对应的header名`,示例:`from-header-x-forwarded-for`,直接获取对端socket ip,配置为`from-remote-addr` | |
| 31 | +| limit_keys | array of object | 是 | - | 配置匹配键值后的限流次数 | |
20 | 32 |
|
21 | 33 | `limit_keys`中每一项的配置字段说明
|
22 | 34 |
|
23 |
| -| 配置项 | 类型 | 必填 | 默认值 | 说明 | |
24 |
| -| ---------------- | ------ | ------------------------------------------------------------ | ------ | ------------------ | |
25 |
| -| key | string | 是 | - | 匹配的键值 | |
26 |
| -| query_per_second | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每秒请求次数 | |
27 |
| -| query_per_minute | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每分钟请求次数 | |
28 |
| -| query_per_hour | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每小时请求次数 | |
29 |
| -| query_per_day | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每天请求次数 | |
| 35 | +| 配置项 | 类型 | 必填 | 默认值 | 说明 | |
| 36 | +| ---------------- | ------ | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | |
| 37 | +| key | string | 是 | - | 匹配的键值,`limit_by_per_header`,`limit_by_per_param`,`limit_by_per_consumer`,`limit_by_per_cookie` 类型支持配置正则表达式(以regexp:开头后面跟正则表达式)或者*(代表所有),正则表达式示例:`regexp:^d.*`(以d开头的所有字符串);`limit_by_per_ip`支持配置 IP 地址或 IP 段 | |
| 38 | +| query_per_second | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每秒请求次数 | |
| 39 | +| query_per_minute | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每分钟请求次数 | |
| 40 | +| query_per_hour | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每小时请求次数 | |
| 41 | +| query_per_day | int | 否,`query_per_second`,`query_per_minute`,`query_per_hour`,`query_per_day` 中选填一项 | - | 允许每天请求次数 | |
30 | 42 |
|
31 | 43 | `redis`中每一项的配置字段说明
|
32 | 44 |
|
33 | 45 | | 配置项 | 类型 | 必填 | 默认值 | 说明 |
|
34 | 46 | | ------------ | ------ | ---- | ---------------------------------------------------------- | --------------------------- |
|
35 |
| -| service_name | string | 必填 | - | 输入redis服务的注册名称 | |
| 47 | +| service_name | string | 必填 | - | redis 服务名称,带服务类型的完整 FQDN 名称,例如 my-redis.dns、redis.my-ns.svc.cluster.local | |
36 | 48 | | service_port | int | 否 | 服务类型为固定地址(static service)默认值为80,其他为6379 | 输入redis服务的服务端口 |
|
37 | 49 | | username | string | 否 | - | redis用户名 |
|
38 | 50 | | password | string | 否 | - | redis密码 |
|
|
43 | 55 | # 配置示例
|
44 | 56 |
|
45 | 57 | ## 识别请求参数 apikey,进行区别限流
|
| 58 | + |
46 | 59 | ```yaml
|
47 |
| -rule_name: limit_by_param_apikey |
48 |
| -limit_by_param: apikey |
49 |
| -limit_keys: |
50 |
| -- key: 9a342114-ba8a-11ec-b1bf-00163e1250b5 |
51 |
| - query_per_second: 10 |
52 |
| -- key: a6a6d7f2-ba8a-11ec-bec2-00163e1250b5 |
53 |
| - query_per_minute: 100 |
| 60 | +rule_name: default_rule |
| 61 | +rule_items: |
| 62 | + - limit_by_param: apikey |
| 63 | + limit_keys: |
| 64 | + - key: 9a342114-ba8a-11ec-b1bf-00163e1250b5 |
| 65 | + query_per_minute: 10 |
| 66 | + - key: a6a6d7f2-ba8a-11ec-bec2-00163e1250b5 |
| 67 | + query_per_hour: 100 |
| 68 | + - limit_by_per_param: apikey |
| 69 | + limit_keys: |
| 70 | + # 正则表达式,匹配以a开头的所有字符串,每个apikey对应的请求10qds |
| 71 | + - key: "regexp:^a.*" |
| 72 | + query_per_second: 10 |
| 73 | + # 正则表达式,匹配以b开头的所有字符串,每个apikey对应的请求100qd |
| 74 | + - key: "regexp:^b.*" |
| 75 | + query_per_minute: 100 |
| 76 | + # 兜底用,匹配所有请求,每个apikey对应的请求1000qdh |
| 77 | + - key: "*" |
| 78 | + query_per_hour: 1000 |
54 | 79 | redis:
|
55 | 80 | service_name: redis.static
|
56 | 81 | show_limit_quota_header: true
|
57 | 82 | ```
|
58 | 83 |
|
| 84 | +
|
| 85 | +
|
59 | 86 | ## 识别请求头 x-ca-key,进行区别限流
|
| 87 | +
|
60 | 88 | ```yaml
|
61 |
| -rule_name: limit_by_param_x-ca-key |
62 |
| -limit_by_header: x-ca-key |
63 |
| -limit_keys: |
64 |
| -- key: 102234 |
65 |
| - query_per_second: 10 |
66 |
| -- key: 308239 |
67 |
| - query_per_hour: 10 |
| 89 | +rule_name: default_rule |
| 90 | +rule_items: |
| 91 | + - limit_by_header: x-ca-key |
| 92 | + limit_keys: |
| 93 | + - key: 102234 |
| 94 | + query_per_minute: 10 |
| 95 | + - key: 308239 |
| 96 | + query_per_hour: 10 |
| 97 | + - limit_by_per_header: x-ca-key |
| 98 | + limit_keys: |
| 99 | + # 正则表达式,匹配以a开头的所有字符串,每个apikey对应的请求10qds |
| 100 | + - key: "regexp:^a.*" |
| 101 | + query_per_second: 10 |
| 102 | + # 正则表达式,匹配以b开头的所有字符串,每个apikey对应的请求100qd |
| 103 | + - key: "regexp:^b.*" |
| 104 | + query_per_minute: 100 |
| 105 | + # 兜底用,匹配所有请求,每个apikey对应的请求1000qdh |
| 106 | + - key: "*" |
| 107 | + query_per_hour: 1000 |
68 | 108 | redis:
|
69 | 109 | service_name: redis.static
|
70 |
| -show_limit_quota_header: true |
| 110 | +show_limit_quota_header: true |
71 | 111 | ```
|
72 | 112 |
|
| 113 | +
|
| 114 | +
|
73 | 115 | ## 根据请求头 x-forwarded-for 获取对端IP,进行区别限流
|
74 | 116 |
|
75 | 117 | ```yaml
|
76 |
| -rule_name: limit_by_per_ip_from-header-x-forwarded-for |
77 |
| -limit_by_per_ip: from-header-x-forwarded-for |
78 |
| -limit_keys: |
79 |
| - # 精确ip |
80 |
| -- key: 1.1.1.1 |
81 |
| - query_per_day: 10 |
82 |
| - # ip段,符合这个ip段的ip,每个ip 100qps |
83 |
| -- key: 1.1.1.0/24 |
84 |
| - query_per_day: 100 |
85 |
| - # 兜底用,即默认每个ip 1000qps |
86 |
| -- key: 0.0.0.0/0 |
87 |
| - query_per_day: 1000 |
| 118 | +rule_name: default_rule |
| 119 | +rule_items: |
| 120 | + - limit_by_per_ip: from-header-x-forwarded-for |
| 121 | + limit_keys: |
| 122 | + # 精确ip |
| 123 | + - key: 1.1.1.1 |
| 124 | + query_per_day: 10 |
| 125 | + # ip段,符合这个ip段的ip,每个ip 100qpd |
| 126 | + - key: 1.1.1.0/24 |
| 127 | + query_per_day: 100 |
| 128 | + # 兜底用,即默认每个ip 1000qpd |
| 129 | + - key: 0.0.0.0/0 |
| 130 | + query_per_day: 1000 |
88 | 131 | redis:
|
89 | 132 | service_name: redis.static
|
90 |
| -show_limit_quota_header: true |
| 133 | +show_limit_quota_header: true |
91 | 134 | ```
|
92 | 135 |
|
93 |
| -## 对特定路由或域名开启 |
| 136 | +
|
| 137 | +
|
| 138 | +## 识别consumer,进行区别限流 |
94 | 139 |
|
95 | 140 | ```yaml
|
96 |
| -# 使用_rules_字段进行细粒度规则配置 |
97 |
| -_rules_: |
98 |
| -# 规则一:按路由名称匹配生效 |
99 |
| -- _match_route_: |
100 |
| - - route-a |
101 |
| - - route-b |
102 |
| - rule_name: limit_rule1 |
103 |
| - limit_by_per_ip: from-header-x-forwarded-for |
104 |
| - limit_keys: |
105 |
| - # 精确ip |
106 |
| - - key: 1.1.1.1 |
107 |
| - query_per_day: 10 |
108 |
| - # ip段,符合这个ip段的ip,每个ip 100qps |
109 |
| - - key: 1.1.1.0/24 |
110 |
| - query_per_day: 100 |
111 |
| - # 兜底用,即默认每个ip 1000qps |
112 |
| - - key: 0.0.0.0/0 |
113 |
| - query_per_day: 1000 |
114 |
| - redis: |
115 |
| - service_name: redis.static |
116 |
| -# 规则二:按域名匹配生效 |
117 |
| -- _match_domain_: |
118 |
| - - "*.example.com" |
119 |
| - - test.com |
120 |
| - rule_name: limit_rule2 |
121 |
| - limit_by_param: apikey |
122 |
| - limit_keys: |
123 |
| - - key: 9a342114-ba8a-11ec-b1bf-00163e1250b5 |
124 |
| - query_per_second: 10 |
125 |
| - - key: a6a6d7f2-ba8a-11ec-bec2-00163e1250b5 |
126 |
| - query_per_minute: 100 |
127 |
| - redis: |
128 |
| - service_name: redis.static |
129 |
| - show_limit_quota_header: true |
| 141 | +rule_name: default_rule |
| 142 | +rule_items: |
| 143 | + - limit_by_consumer: '' |
| 144 | + limit_keys: |
| 145 | + - key: consumer1 |
| 146 | + query_per_second: 10 |
| 147 | + - key: consumer2 |
| 148 | + query_per_hour: 100 |
| 149 | + - limit_by_per_consumer: '' |
| 150 | + limit_keys: |
| 151 | + # 正则表达式,匹配以a开头的所有字符串,每个consumer对应的请求10qds |
| 152 | + - key: "regexp:^a.*" |
| 153 | + query_per_second: 10 |
| 154 | + # 正则表达式,匹配以b开头的所有字符串,每个consumer对应的请求100qd |
| 155 | + - key: "regexp:^b.*" |
| 156 | + query_per_minute: 100 |
| 157 | + # 兜底用,匹配所有请求,每个consumer对应的请求1000qdh |
| 158 | + - key: "*" |
| 159 | + query_per_hour: 1000 |
| 160 | +redis: |
| 161 | + service_name: redis.static |
| 162 | +show_limit_quota_header: true |
| 163 | +``` |
| 164 | +
|
| 165 | +
|
| 166 | +
|
| 167 | +## 识别cookie中的键值对,进行区别限流 |
| 168 | +
|
| 169 | +```yaml |
| 170 | +rule_name: default_rule |
| 171 | +rule_items: |
| 172 | + - limit_by_cookie: key1 |
| 173 | + limit_keys: |
| 174 | + - key: value1 |
| 175 | + query_per_minute: 10 |
| 176 | + - key: value2 |
| 177 | + query_per_hour: 100 |
| 178 | + - limit_by_per_cookie: key1 |
| 179 | + limit_keys: |
| 180 | + # 正则表达式,匹配以a开头的所有字符串,每个cookie中的value对应的请求10qds |
| 181 | + - key: "regexp:^a.*" |
| 182 | + query_per_second: 10 |
| 183 | + # 正则表达式,匹配以b开头的所有字符串,每个cookie中的value对应的请求100qd |
| 184 | + - key: "regexp:^b.*" |
| 185 | + query_per_minute: 100 |
| 186 | + # 兜底用,匹配所有请求,每个cookie中的value对应的请求1000qdh |
| 187 | + - key: "*" |
| 188 | + query_per_hour: 1000 |
| 189 | +rejected_code: 200 |
| 190 | +rejected_msg: '{"code":-1,"msg":"Too many requests"}' |
| 191 | +redis: |
| 192 | + service_name: redis.static |
| 193 | +show_limit_quota_header: true |
130 | 194 | ```
|
131 |
| -此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置; |
132 |
| -此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将使用此段配置; |
133 |
| -配置的匹配生效顺序,将按照 `_rules_` 下规则的排列顺序,匹配第一个规则后生效对应配置,后续规则将被忽略 |
|
0 commit comments