在高流量冲击、潜在服务过载、资源耗尽或恶意攻击等情况下,您可以在流量管理中心配置本地限流,将流量维持在可控的阈值内,确保服务持续可用并维持性能稳定。本地限流通过Envoy代理实现,它采用令牌桶算法来控制向服务端的请求流量。此算法定期向令牌桶添加令牌,每个请求消耗一枚令牌。令牌耗尽时,系统将暂停接受新请求,有效预防过载情况发生。
前提条件
已创建ASM实例,且ASM实例符合以下要求:
ASM商业版(专业版或旗舰版):版本需为1.14.3及以上。关于升级ASM实例的具体操作,请参见升级ASM实例。
ASM标准版:仅支持Istio原生方式配置本地限流功能,且版本需为1.9及以上。不同Istio版本需参考相应版本文档,关于最新的Istio版本配置本地限流功能的具体操作,请参见Enabling Rate Limits using Envoy。
已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例。
已为Kubernetes集群中的default命名空间开启自动注入。具体操作,请参见启用自动注入。
准备工作
部署httpbin和sleep示例服务,并验证sleep服务能否正常访问httpbin服务。
使用以下内容,创建httpbin.yaml。
执行以下命令,创建httpbin应用。
kubectl apply -f httpbin.yaml -n default
使用以下内容,创建sleep.yaml。
执行以下命令,创建sleep应用。
kubectl apply -f sleep.yaml -n default
执行以下命令,进入sleep环境开启bash。
kubectl exec -it deploy/sleep -- sh
执行以下命令,向httpbin服务发送请求。
curl -I http://httpbin:8000/headers
预期输出:
HTTP/1.1 200 OK server: envoy date: Tue, 26 Dec 2023 07:23:49 GMT content-type: application/json content-length: 353 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 1
返回
200 OK
,表明访问成功。
场景一:对服务的特定端口进行限流
对httpbin服务的8000端口进行限流。配置限流规则后,发往httpbin服务8000端口的所有请求都将受到流量速率限制。
创建本地限流规则。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ,然后单击创建。
在创建页面,按需进行以下配置,然后单击确定。
配置区域
配置项
说明
限流基本信息
命名空间
本地限流配置的命名空间,需要配置为限流生效的工作负载的所在命名空间。本示例选择default。
名称
本地限流配置的自定义名称。本示例填写httpbin。
生效工作负载类型
限流生效的工作负载类型,支持应用服务生效和网关生效。本示例选择应用服务生效。
关联工作负载
需要填写一系列标签键值对,以选中具体工作负载。本示例填写标签名为app,标签值为httpbin。
限流规则列表
服务Service端口
填写服务的Kubernetes Service中声明的端口号,需要为HTTP端口。本示例填写httpbin服务的HTTP端口8000。
限流配置
指定本地限流令牌桶算法的检测时间窗口长度与时间窗口内允许的请求数量。在时间窗口内发送的请求数量超过该允许的数量则会对请求进行限流。本示例配置如下:
限流检测时间窗口填写60秒。
时间窗口内允许请求数量填写10。
以上配置表示发往此服务的工作负载的请求不得在60秒内连续发送10个以上。
以上配置对应的本地限流配置YAML如下。
验证本地限流规则。
执行以下命令,进入sleep环境开启bash。
kubectl exec -it deploy/sleep -- sh
执行以下命令,发送10个请求。
for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; done
执行以下命令,发送第11个请求。
curl -v http://httpbin:8000/headers
预期输出:
* Trying 172.16.245.130:8000... * Connected to httpbin (172.16.245.130) port 8000 > GET /headers HTTP/1.1 > Host: httpbin:8000 > User-Agent: curl/8.5.0 > Accept: */* > < HTTP/1.1 429 Too Many Requests < x-local-rate-limit: true < content-length: 18 < content-type: text/plain < date: Tue, 26 Dec 2023 08:02:58 GMT < server: envoy < x-envoy-upstream-service-time: 2
由预期输出得到,返回HTTP 429的状态码。请求已被限流。
场景二:在服务特定端口上,针对发往指定路径的请求进行限流
对httpbin服务的8000端口进行限流,并限制限流只生效在访问/headers
路径的请求上。配置限流规则后,发往httpbin服务8000端口、且访问路径/headers
的所有请求都将受到流量速率限制。
创建本地限流规则。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 ,然后单击创建。
在创建页面,按需进行以下配置,然后单击确定。
配置区域
配置项
说明
限流基本信息
命名空间
本地限流配置的命名空间,需要配置为限流生效的工作负载的所在命名空间。本示例选择default。
名称
本地限流配置的自定义名称。本示例填写httpbin。
生效工作负载类型
限流生效的工作负载类型,支持应用服务生效和网关生效。本示例选择应用服务生效。
关联工作负载
需要填写一系列标签键值对,以选中具体工作负载。本示例填写标签名为app,标签值为httpbin。
限流规则列表
服务Service端口
填写服务的Kubernetes Service中声明的端口号,需要为HTTP端口。本示例填写httpbin服务的HTTP端口8000。
匹配请求属性
填写生效限流配置的具体请求匹配规则。本示例配置如下:
匹配属性选择请求路径。
匹配方法选择前缀匹配。
匹配内容填写
/headers
。
限流配置
指定本地限流令牌桶算法的检测时间窗口长度与时间窗口内允许的请求数量。在时间窗口内发送的请求数量超过该允许的数量则会对请求进行限流。本示例配置如下:
限流检测时间窗口填写60秒。
时间窗口内允许请求数量填写10。
以上配置表示发往此服务的工作负载的请求不得在60秒内连续发送10个以上。
验证本地限流规则。
执行以下命令,进入sleep环境开启bash。
kubectl exec -it deploy/sleep -- sh
执行以下命令,发送10个请求。
for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; done
执行以下命令,发送第11个请求。
curl -v http://httpbin:8000/headers
预期输出:
* Trying 172.16.245.130:8000... * Connected to httpbin (172.16.245.130) port 8000 > GET /headers HTTP/1.1 > Host: httpbin:8000 > User-Agent: curl/8.5.0 > Accept: */* > < HTTP/1.1 429 Too Many Requests < x-local-rate-limit: true < content-length: 18 < content-type: text/plain < date: Tue, 26 Dec 2023 08:02:58 GMT < server: envoy < x-envoy-upstream-service-time: 2
由预期输出得到,返回HTTP 429的状态码。请求已被限流。
执行以下命令,向httpbin服务的
/get
路径发送请求。curl -v http://httpbin:8000/get
预期输出:
* Trying 192.168.243.21:8000... * Connected to httpbin (192.168.243.21) port 8000 (#0) > GET /get HTTP/1.1 > Host: httpbin:8000 > User-Agent: curl/8.1.2 > Accept: */* > < HTTP/1.1 200 OK < server: envoy < date: Thu, 11 Jan 2024 03:46:11 GMT < content-type: application/json < content-length: 431 < access-control-allow-origin: * < access-control-allow-credentials: true < x-envoy-upstream-service-time: 1 < { "args": {}, "headers": { "Accept": "*/*", "Host": "httpbin:8000", "User-Agent": "curl/8.1.2", "X-Envoy-Attempt-Count": "1", "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=be10819991ba1a354a89e68b3bed1553c12a4fba8b65fbe0f16299d552680b29;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep" }, "origin": "127.0.0.6", "url": "http://httpbin:8000/get" }
由预期输出得到,返回200状态码。发往httpbin服务的其他路径的请求并未受到限流规则影响。
相关操作
查看本地限流相关指标
本地限流功能会产生以下指标:
Metric | 描述 |
envoy_http_local_rate_limiter_http_local_rate_limit_enabled | 触发限流的请求总数。 |
envoy_http_local_rate_limiter_http_local_rate_limit_ok | 来自令牌桶的限流响应总数。 |
envoy_http_local_rate_limiter_http_local_rate_limit_rate_limited | 没有令牌的请求总数(但不一定强制执行限流)。 |
envoy_http_local_rate_limiter_http_local_rate_limit_enforced | 最终收到限流响应的总数(例如返回429)。 |
您可以通过配置Sidecar代理的proxyStatsMatcher使Sidecar代理上报相关指标,然后使用Prometheus采集并查看限流相关指标。
通过proxyStatsMatcher配置Sidecar代理上报限流指标。
在配置proxyStatsMatcher时,选中正则匹配,配置为
.*http_local_rate_limit.*
;或者直接单击添加本地限流指标。具体操作,请参见proxyStatsMatcher。重新部署httpbin无状态工作负载。具体操作,请参见重新部署工作负载。
新创建的httpbin Pod中的Sidecar代理将可以上报限流相关指标。
执行以下命令,查看httpbin服务的本地限流相关指标。
kubectl exec -it deploy/httpbin -c istio-proxy -- curl localhost:15020/stats/prometheus|grep http_local_rate_limit
预期输出:
envoy_http_local_rate_limiter_http_local_rate_limit_enabled{} 37 envoy_http_local_rate_limiter_http_local_rate_limit_enforced{} 17 envoy_http_local_rate_limiter_http_local_rate_limit_ok{} 20 envoy_http_local_rate_limiter_http_local_rate_limit_rate_limited{} 17
相关文档
若您的ASM版本为1.19.0及以上,本地限流YAML还支持通过
limit_overrides
字段对请求查询参数等其他请求属性进行匹配。更多信息,请参见ASMLocalRateLimiter CRD说明。您可以使用ASMGlobalRateLimiter CRD,对入口网关和应用服务入口流量配置全局限流。具体操作,请参见使用ASMGlobalRateLimiter对应用服务入口流量配置全局限流。
您可以通过ASM控制台为入口网关配置本地限流或全局限流。具体操作,请参见为入口网关配置本地限流和为入口网关配置全局限流。
您可以使用慢启动预热功能,在规定时间段内逐步增加请求量,避免出现请求超时、数据丢失等问题。具体操作,请参见使用ASM慢启动预热功能。
您可以配置连接池实现熔断功能,在系统出现故障或超负荷的情况下,保护系统免受进一步的损害。具体操作,请参见配置连接池实现熔断功能。