实验 5:局部速率限制
在这个实验中,我们将学习如何配置一个局部速率限制器。我们将使用运行在 3030 端口的 httpbin
容器。
docker run -d -p 3030:80 kennethreitz/httpbin
让我们创建一个有五个令牌的速率限制器。每隔 30 秒,速率限制器就会向桶里补充 5 个令牌。
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: instance_1
domains: ["*"]
routes:
- match:
prefix: /status
route:
cluster: instance_1
- match:
prefix: /headers
route:
cluster: instance_1
typed_per_filter_config:
envoy.filters.http.local_ratelimit:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: headers_route
token_bucket:
max_tokens: 5
tokens_per_fill: 5
fill_interval: 30s
filter_enabled:
default_value:
numerator: 100
denominator: HUNDRED
filter_enforced:
default_value:
numerator: 100
denominator: HUNDRED
response_headers_to_add:
- append: false
header:
key: x-rate-limited
value: OH_NO
http_filters:
- name: envoy.filters.http.local_ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: httpbin_rate_limiter
- name: envoy.filters.http.router
clusters:
- name: instance_1
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: instance_1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 3030
admin:
address:
socket_address:
address: 127.0.0.1
port_value: 9901
将上述 YAML 保存为 2-lab-5-local-rate-limiter-1.yaml
,用 func-e run -c 2-lab-5-local-rate-limiter-1.yaml
运行 Envoy。
上述配置为路由 /headers
启用了一个局部速率限制器。此外,一旦达到速率限制,我们将在响应中添加一个头信息(x-rate-limited
)。
如果我们在 30 秒内向 http://localhost:10000/headers
发出超过 5 个请求,我们会得到 HTTP 429 的响应。
$ curl -v localhost:10000/headers
...
> GET /headers HTTP/1.1
> Host: localhost:10000
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 429 Too Many Requests
< x-rate-limited: OH_NO
...
local_rate_limited
另外,注意到 Envoy 设置的 x-rate-limited
头。
一旦我们被限制了速率,我们将不得不等待 30 秒,让速率限制器再次用令牌把桶填满。我们也可以尝试向 /status/200
发出请求,你会发现我们不会在这个路径上受到速率限制。
如果我们打开统计页面(localhost:9901/stats/prometheus
),我们会发现限速指标是使用我们配置的 headers_route_rate_limiter
统计前缀记录的。
# TYPE envoy_headers_route_http_local_rate_limit_enabled counter
envoy_headers_route_http_local_rate_limit_enabled{} 13
# TYPE envoy_headers_route_http_local_rate_limit_enforced counter
envoy_headers_route_http_local_rate_limit_enforced{} 8
# TYPE envoy_headers_route_http_local_rate_limit_ok counter
envoy_headers_route_http_local_rate_limit_ok{} 5
# TYPE envoy_headers_route_http_local_rate_limit_rate_limited counter
envoy_headers_route_http_local_rate_limit_rate_limited{} 8