跳到主要内容

限流

本地限流

本地限流的意思是只针对单个代理 (ingressgateway 或 sidecar) 的速率限制,不是全局的,不过一般用本地限流就足够了,能够起到保护后端不过载的作用。

实现方式是配置 EnvoyFilter,让 Envoy 本地统计请求的 QPS,然后根据统计数据判断是否要限流。

加注解

在配置 EnvoyFilter 前首先在要在部署 workload 时给 pod 加注解配置让 Envoy 启用 http_local_rate_limit 的统计数据 ,示例(注意高亮部分):

apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
annotations:
proxy.istio.io/config: |-
proxyStatsMatcher:
inclusionRegexps:
- ".*http_local_rate_limit.*"
labels:
app: productpage
version: v1
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.17.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {}

创建 EnvoyFilter

然后根据限流需求创建 EnvoyFilter,示例:

local-ratelimit-workload.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: local-ratelimit-workload
namespace: mesh-test # workload 所在 namespace
spec:
# 只限制 productpage 工作负载的 QPS
workloadSelector:
labels:
app: productpage
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.local_ratelimit
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
value:
stat_prefix: http_local_rate_limiter
token_bucket:
# 限制每分钟 10 个请求
max_tokens: 10
tokens_per_fill: 10
fill_interval: 60s
filter_enabled:
runtime_key: local_rate_limit_enabled
default_value:
numerator: 100
denominator: HUNDRED
filter_enforced:
runtime_key: local_rate_limit_enforced
default_value:
numerator: 100
denominator: HUNDRED
response_headers_to_add:
- append: false
header:
key: x-local-rate-limit
value: "true"

全局限流

全局限流的意思是在全局限制 QPS,既然是全局,那必然有单独的地方存储请求的统计数据,一般使用自行部署的 redis 来存储,然后限流服务根据 redis 中全局的统计数据判断是否要限流。

这个相对麻烦,可参考 官方文档

参考资料