关注“之家技术”,获取更多技术干货
总篇286篇 2024年第2篇
1. 项目背景
2. 服务限流
2.1
本地限流
本地限流需要通过EnvoyFilter来实现,他不会请求外部服务,在envoy内部实现支持,而不需要依赖外部的流量控制组件。这种限流机制通过在应用程序中实施并监控一定的策略,来控制请求的发送速率或并发数,以确保底层的服务资源不会被过度使用或超载,其本质是一个令牌桶的算法。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-local-ratelimit-svc
spec:
workloadSelector:
labels:
app: productpage
configPatches:
applyTo: HTTP_FILTER
match:
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.local_ratelimit
typed_config:
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 #表示生成stat的指标前缀
token_bucket: #配置令牌桶
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表示修改,true表示添加。
append: false
header:
key: x-local-rate-limit
value: 'true'
2.2
全局限流
健康检查
GET http://{ratelimitServiceName}:8080/healthcheck
domain: ratelimit_demo01
descriptors:
key: demoKey
value: users
rate_limit:
unit: second
requests_per_unit: 500
key: demoKey
value: default
rate_limit:
unit: second
requests_per_unit: 500
{
"domain": "ratelimit_demo01",
"descriptors": [
{
"key": "demoKey",
"value": "users",
"rate_limit": {
"unit": 1, # second:1 minute:2 hour:3 day:4
"requests_per_unit": 500
}
},
{
"key": "Remote_IP",
"value": "default",
"rate_limit": {
"unit": 1, # second:1 minute:2 hour:3 day:4
"requests_per_unit": 500
}
}
]
}
插件作用
x-forwarded-for= 2409:8910:688:ab45:8542:c124:5236:128b,111.63.51.91, 182.138.255.115
x-forwarded-for-0 = 2409:8910:688:ab45:8542:c124:5236:128b
x-forwarded-for-1 = 111.63.51.91
x-forwarded-for-2 = 182.138.255.11
:path=/getUser?name=autohome
x-path-0 = /getUser
# 为服务名[dotnet-car-automesh-10001] 定义规则 IP=10.18.162.163 and path=/api/trace/health ,限速规则为 5次/分钟
{
"domain": "dotnet-car-automesh-10001",
"descriptors": [
{
"key": "pathRaliemit",
"value": "/api/trace/health",
"descriptors": [
{
"key": "Remote_IP",
"value": "10.18.162.163",
"detailed_metric": true,
"shadow_mode": false,
"rate_limit": {
"unit": 2,
"requests_per_unit": 5
}
}
]
}
]
}
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit-dotnetdemo
namespace: en-888
spec:
workloadSelector:
# select by label in the same namespace
labels:
app_service: dotnet-demo-yzmeshjava-36643
configPatches:
# The Envoy config you want to modify
applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
# Adds the Envoy Rate Limit Filter in HTTP filter chain.
value:
name: envoy.filters.http.ratelimit
typed_config:
type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit :
domain: automesh-ratelimit
failure_mode_deny: false
request_type: both # internal、external、both
timeout: 20ms
rate_limited_as_resource_exhausted: true
enable_x_ratelimit_headers: DRAFT_VERSION_03
disable_x_envoy_ratelimited_header: false
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: rate_limit_cluster
timeout: 10s
transport_api_version: V3
applyTo: CLUSTER
match:
cluster:
service: ratelimit.ratelimit
patch:
operation: ADD
# Adds the rate limit service cluster for rate limit service defined in step 1.
value:
name: rate_limit_cluster
type: STRICT_DNS
connect_timeout: 10s
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
cluster_name: rate_limit_cluster
endpoints:
lb_endpoints:
endpoint:
address:
socket_address:
address: ratelimit.ratelimit
8081 :
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit-svc-{app_service}
namespace: en-888
spec:
workloadSelector:
labels:
app_service: {app_service}
configPatches:
applyTo: VIRTUAL_HOST
match:
context: SIDECAR_INBOUND
routeConfiguration:
vhost:
name: "inbound|http|8080"
route:
action: ANY
patch:
operation: MERGE
# Applies the rate limit rules.
value:
rate_limits:
actions:
request_headers:
header_name: "x-path-0"
descriptor_key: "pathRaliemit"
request_headers:
header_name: "x-forwarded-for-0"
descriptor_key: "remoteIPRaliemit"
测试
3. 服务熔断
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: dotnet-car-automesh
spec:
host: dotnet-car-automesh-10001.autohome.com
trafficPolicy:
outlierDetection:
consecutive5xxErrors: 10
interval: 5s
baseEjectionTime: 5s
maxEjectionPercent: 100
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: match
spec:
workloadSelector:
labels:
app_service: dotnet-car-automesh
configPatches:
applyTo: CLUSTER
match:
cluster:
name: outbound|8080||dotnet-car-automesh-10001.autohome.com
patch:
operation: MERGE
value:
outlierDetection:
consecutive5xxErrors: 10
interval: 5s
baseEjectionTime: 5s
maxEjectionPercent: 100
4. 总结
参考:
https://github.com/envoyproxy/data-plane-api
https://github.com/envoyproxy/ratelimit
https://cloudnative.to/blog/istio-circuit-breaking/
https://istio.io/latest/zh/docs/tasks/traffic-management/circuit-breaking/
作者简介
李建彪
■ 服务端研发部-服务端看选技术团队-基础架构组
■ 简介:擅长微服务架构、云原生架构体系,主要负责汽车之家服务端云原生服务网格化改造。
阅读更多:
▼ 关注「之家技术」,获取更多技术干货 ▼