Skip to content

Commit

Permalink
feat(limit-conn): support multiple variables as key in L4 (#5413)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacewander committed Nov 4, 2021
1 parent 1083359 commit 4dafab5
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 16 deletions.
7 changes: 4 additions & 3 deletions apisix/stream/plugins/limit-conn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ local schema = {
burst = {type = "integer", minimum = 0},
default_conn_delay = {type = "number", exclusiveMinimum = 0},
only_use_default_delay = {type = "boolean", default = false},
key = {
type = "string",
enum = {"remote_addr", "server_addr"}
key = {type = "string"},
key_type = {type = "string",
enum = {"var", "var_combination"},
default = "var",
},
},
required = {"conn", "burst", "default_conn_delay", "key"}
Expand Down
4 changes: 0 additions & 4 deletions docs/en/latest/plugins/limit-conn.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ Limiting request concurrency plugin.
| rejected_msg | string | optional | | non-empty | the response body returned when the request exceeds `conn` + `burst` will be rejected. |
| allow_degradation | boolean | optional | false | | Whether to enable plugin degradation when the limit-conn function is temporarily unavailable. Allow requests to continue when the value is set to true, default false. |

**Key can be customized by the user, only need to modify a line of code of the plug-in to complete. It is a security consideration that is not open in the plugin.**

When used in the stream proxy, only `remote_addr` and `server_addr` can be used as key. And `rejected_code` is meaningless.

## How To Enable

Here's an example, enable the limit-conn plugin on the specified route:
Expand Down
2 changes: 0 additions & 2 deletions docs/en/latest/plugins/limit-req.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ limit request rate using the "leaky bucket" method.
| nodelay | boolean | optional | false | | If nodelay flag is true, bursted requests will not get delayed |
| allow_degradation | boolean | optional | false | | Whether to enable plugin degradation when the limit-req function is temporarily unavailable. Allow requests to continue when the value is set to true, default false. |

**Key can be customized by the user, only need to modify a line of code of the plug-in to complete. It is a security consideration that is not open in the plugin.**

## Example

### How to enable on the `route` or `service`
Expand Down
4 changes: 0 additions & 4 deletions docs/zh/latest/plugins/limit-conn.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ title: limit-conn
| rejected_msg | string | 可选 | | 非空 | 当请求超过 `conn` + `burst` 这个阈值时,返回的响应体。 |
| allow_degradation | boolean | 可选 | false | | 当插件功能临时不可用时是否允许请求继续。当值设置为 true 时则自动允许请求继续,默认值是 false。|

**注:key 是可以被用户自定义的,只需要修改插件的一行代码即可完成。并没有在插件中放开是处于安全的考虑。**

在 stream 代理中使用该插件时,只有 `remote_addr``server_addr` 可以被用作 key。另外设置 `rejected_code` 毫无意义。

#### 如何启用

下面是一个示例,在指定的 route 上开启了 limit-conn 插件:
Expand Down
2 changes: 0 additions & 2 deletions docs/zh/latest/plugins/limit-req.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ title: limit-req
| nodelay | boolean | 可选 | false | | 如果 nodelay 为 true, 请求速率超过 `rate` 但没有超过 (`rate` + `brust`)的请求不会加上延迟, 如果是 false,则会加上延迟。 |
| allow_degradation | boolean | 可选 | false | | 当限速插件功能临时不可用时是否允许请求继续。当值设置为 true 时则自动允许请求继续,默认值是 false。|

**key 是可以被用户自定义的,只需要修改插件的一行代码即可完成。并没有在插件中放开是处于安全的考虑。**

## 示例

### 如何在`route``service`上使用
Expand Down
2 changes: 1 addition & 1 deletion t/admin/plugins.t
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ qr/\{"properties":\{"password":\{"type":"string"\},"username":\{"type":"string"\
}
}
--- response_body
{"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"burst":{"minimum":0,"type":"integer"},"conn":{"exclusiveMinimum":0,"type":"integer"},"default_conn_delay":{"exclusiveMinimum":0,"type":"number"},"disable":{"type":"boolean"},"key":{"enum":["remote_addr","server_addr"],"type":"string"},"only_use_default_delay":{"default":false,"type":"boolean"}},"required":["conn","burst","default_conn_delay","key"],"type":"object"},"version":0.1}
{"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"burst":{"minimum":0,"type":"integer"},"conn":{"exclusiveMinimum":0,"type":"integer"},"default_conn_delay":{"exclusiveMinimum":0,"type":"number"},"disable":{"type":"boolean"},"key":{"type":"string"},"key_type":{"default":"var","enum":["var","var_combination"],"type":"string"},"only_use_default_delay":{"default":false,"type":"boolean"}},"required":["conn","burst","default_conn_delay","key"],"type":"object"},"version":0.1}
--- no_error_log
[error]
Expand Down
145 changes: 145 additions & 0 deletions t/stream-plugin/limit-conn.t
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,148 @@ GET /test_concurrency
--- error_log
Connection reset by peer
--- stream_enable
=== TEST 5: var combination
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/stream_routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"limit-conn": {
"conn": 2,
"burst": 1,
"default_conn_delay": 0.1,
"key": "$remote_addr $server_addr",
"key_type": "var_combination"
}
},
"upstream_id": "1"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
=== TEST 6: exceeding the burst
--- request
GET /test_concurrency
--- response_body
200
200
200
503
503
--- error_log
Connection reset by peer
--- stream_enable
=== TEST 7: var combination (not exceed the burst)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/stream_routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"limit-conn": {
"conn": 2,
"burst": 1,
"default_conn_delay": 0.1,
"key": "$remote_port $server_addr",
"key_type": "var_combination"
}
},
"upstream_id": "1"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
=== TEST 8: hit
--- request
GET /test_concurrency
--- response_body
200
200
200
200
200
--- stream_enable
=== TEST 9: bypass empty key
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/stream_routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {
"limit-conn": {
"conn": 2,
"burst": 1,
"default_conn_delay": 0.1,
"key": "$proxy_protocol_addr $proxy_protocol_port",
"key_type": "var_combination"
}
},
"upstream_id": "1"
}]]
)
if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
=== TEST 10: hit
--- request
GET /test_concurrency
--- response_body
200
200
200
200
200
--- error_log
bypass the limit conn as the key is empty
--- stream_enable

0 comments on commit 4dafab5

Please sign in to comment.