在 Envoy Gateway 中,流量控制与优化是确保系统可靠性和稳定性的关键功能。通过灵活的重试策略、熔断器配置、全局速率限制以及连接限制等机制,Envoy Gateway 提供了丰富的工具来优化服务性能,防止系统过载,并保障服务的高可用性。此外,超时管理和故障注入功能使得开发者可以更好地测试和优化服务的鲁棒性,从而应对复杂的生产环境挑战。本章将详细介绍这些流量控制与优化策略的配置和应用方法。
重试策略
重试策略是在请求失败时进行多次重试,以提升服务的可靠性。在EG中,通过自定义CRD BackendTrafficPolicy
来实现重试配置。该CRD允许你指定重试次数、条件以及每次重试的策略,并可以将其关联到 Gateway
、HTTPRoute
或 GRPCRoute
资源上。
配置示例:
定义一个 BackendTrafficPolicy
资源,为名为 backend
的 HTTPRoute
配置重试策略,允许在遇到 HTTP 500 错误、连接失败或其他可重试状态时最多重试 5 次,每次重试的超时时间为 250 毫秒,并使用 100 毫秒到 10 秒的指数退避策略。
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: retry-for-route
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
retry:
numRetries: 5
perRetry:
backOff:
baseInterval: 100ms
maxInterval: 10s
timeout: 250ms
retryOn:
httpStatusCodes:
- 500
triggers:
- connect-failure
- retriable-status-codes
熔断器
熔断器是另一项关键功能,它通过限制请求数量来防止服务过载,确保系统的稳定性。与重试策略类似,熔断器配置也是通过 BackendTrafficPolicy
CRD 来实现。即便一个熔断器策略作用于一个 Gateway
或 Route
,每个 BackendReference
的熔断器计数器仍然是独立的。
Envoy Gateway 支持以下熔断器阈值:
- 并发连接(Concurrent Connections):限制 Envoy 可以与上游服务建立的连接数量,当达到此阈值时,不会建立新的连接,部分请求将被排队,直到现有连接可用。
- 并发请求(Concurrent Requests):限制 Envoy 与上游服务之间的并发请求数量,当达到此阈值时,请求将被排队。
- 待处理请求(Pending Requests):限制待处理请求队列的大小,当达到此阈值时,超出的请求将以 503 状态码终止。
配置示例:
定义一个 BackendTrafficPolicy
资源,为名为 backend
的 HTTPRoute
配置熔断器策略,限制最大并发请求数为 10,并将待处理请求的最大数量设置为 0,意味着不允许有待处理请求。
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: circuit-breaker-policy
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
circuitBreaker:
maxPendingRequests: 0
maxParallelRequests: 10
全局速率限制
全局速率限制功能允许你在所有运行 Envoy 代理的实例上应用共享的请求速率限制。无论请求通过哪一个 Envoy 实例,只要超过设定的总请求限额,都会被限制。该功能也通过 BackendTrafficPolicy
来实现,适用于多个后端服务的全局流量控制。
配置步骤:
-
安装 Redis:全局速率限制依赖于 Envoy 的 Rate Limit 组件,并且需要一个 Redis 实例作为缓存层。你需要在 Kubernetes 集群中部署 Redis,并确保其正常运行。
-
配置 Envoy Gateway:更新 Envoy Gateway 的配置,将全局速率限制功能启用,并将 Redis 实例的 URL 配置到 Envoy Gateway 的
ConfigMap
中。之后,你需要重新启动 Envoy Gateway 以应用新的配置。 -
定义 BackendTrafficPolicy:使用
BackendTrafficPolicy
CRD 来定义全局速率限制策略。你可以将该策略与Gateway
、HTTPRoute
或GRPCRoute
资源关联,定义具体的速率限制规则。 -
配置速率限制规则:通过
BackendTrafficPolicy
,你可以针对特定的请求路径、请求头或用户标识符配置速率限制。例如,你可以限制每个用户在一小时内最多发起 3 次请求。
配置示例:
定义一个 BackendTrafficPolicy
资源,为名为 http-ratelimit
的 HTTPRoute
配置全局速率限制策略。当请求包含 x-user-id
头部且值为 one
时,限制每小时最多 3 个请求。超出限制的请求将返回 429 Too Many Requests
状态码。
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
type: Global
global:
rules:
- clientSelectors:
- headers:
- name: x-user-id
value: one
limit:
requests: 3
unit: Hour
连接限制
连接限制功能允许你控制每个服务的最大并发连接数,以防止服务过载。在 HTTPRoute
对象中配置 RequestConnectionLimit
可以实现该功能。
Envoy Gateway 引入了一个新的 CRD,称为 ClientTrafficPolicy
,允许用户配置所需的连接限制设置。该配置可以绑定到一个 Gateway
资源上。
配置示例:
定义一个 ClientTrafficPolicy
资源,为名为 eg
的 Gateway 配置连接限制策略,限制每个客户端的连接数最多为 5 个。
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
name: connection-limit-ctp
namespace: default
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: eg
connection:
connectionLimit:
value: 5
超时管理
超时管理允许你为 HTTP 请求和响应设置最大时间限制,以避免长时间等待导致资源占用。在 HTTPRoute
对象中,可以通过 RequestTimeout
来配置超时设置。
配置示例:
定义一个 HTTPRoute
资源,将所有发送到 timeout.example.com
的请求路由到名为 backend
的服务的 3000 端口,并为请求设置了 2 秒的超时时间。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: backend
spec:
hostnames:
- timeout.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: eg
rules:
- backendRefs:
- group: ""
kind: Service
name: backend
port: 3000
weight: 1
matches:
- path:
type: PathPrefix
value: /
timeouts:
request: "2s"
故障注入
故障注入功能允许你模拟服务故障,通过注入延迟或错误来测试系统的鲁棒性和故障恢复能力。
支持的故障场景:
- 延迟故障:以一定概率向请求中注入固定的延迟,模拟延迟故障。
- 终止故障:以一定概率向响应中注入特定的 HTTP 状态码,模拟请求终止故障。
Envoy Gateway 引入了一个名为 BackendTrafficPolicy
的自定义资源,允许用户定义所需的故障注入场景。该资源可以关联到 Gateway
、HTTPRoute
或 GRPCRoute
。
配置示例:
定义一个 BackendTrafficPolicy
资源,为名为 foo
的 HTTPRoute
配置了 50% 的故障注入策略,即将 50% 的请求返回 501 状态码。
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: fault-injection-50-percent-abort
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: foo
faultInjection:
abort:
httpStatus: 501
percentage: 50