来源:之家技术
1. 项目背景


2. 服务限流
2.1
本地限流

本地限流需要通过EnvoyFilter来实现,他不会请求外部服务,在envoy内部实现支持,而不需要依赖外部的流量控制组件。这种限流机制通过在应用程序中实施并监控一定的策略,来控制请求的发送速率或并发数,以确保底层的服务资源不会被过度使用或超载,其本质是一个令牌桶的算法。
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: filter-local-ratelimit-svcspec: 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": 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 } } ]}
客户端直接访问汽车之家网站 客户端访问CDN,回源到汽车之家后端服务
插件作用
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:128bx-forwarded-for-1 = 111.63.51.91x-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/v1alpha3kind: EnvoyFiltermetadata: name: filter-ratelimit-dotnetdemo namespace: en-888spec: 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": 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 port_value: 8081
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: filter-ratelimit-svc-{app_service} namespace: en-888spec: 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. 服务熔断
设置连接池connectionPool为服务配置连接的数量,实现限流熔断; 设置异常检测outlierDetection控制从负载均衡池中剔除不健康的实例,实现服务实例隔离熔断。
apiVersion: networking.istio.io/v1beta1kind: DestinationRulemetadata: name: dotnet-car-automeshspec: host: dotnet-car-automesh-10001.autohome.com trafficPolicy: outlierDetection: consecutive5xxErrors: 10 interval: 5s baseEjectionTime: 5s maxEjectionPercent: 100
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata: name: matchspec: 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/