限流是一种限制发送到服务端的请求数量的机制。它指定客户端在给定时间段内可以向服务端发送的最大请求数,通常表示为一段时间内的请求数,例如每分钟300个请求或每秒10个请求等。服务网格ASM自1.18.0.131版本起,支持针对入口网关和注入了Sidecar的应用服务的入口流量配置全局限流。本文介绍如何在ASM中使用ASMGlobalRateLimiter对应用服务入口流量配置全局限流。
前提条件
已添加Kubernetes托管版集群到ASM实例,且ASM实例为1.18.X.XXX及以上。具体操作,请参见添加集群到ASM实例。
已为Kubernetes集群中的default命名空间开启自动注入。具体操作,请参见启用自动注入。
已创建名为ingressgateway的入口网关,并开启80端口。具体操作,请参见创建入口网关。
已完成sleep和httpbin示例应用的部署。具体操作,请参见在数据面集群中部署httpbin应用和在数据面集群部署sleep服务。
部署限流服务
您需要先在数据面集群中部署限流服务,才能使全局限流功能生效。部署限流服务和示例应用的步骤如下。
Envoy代理实现限流主要有两种方式:全局限流、本地限流。本文仅介绍全局限流的配置方法。关于限流的相关概念以及如何配置本地限流,请参见在流量管理中心配置本地限流。
使用以下内容,创建ratelimit-svc.yaml。
在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中创建限流服务和限流服务依赖的Redis服务。
kubectl apply -f ratelimit-svc.yaml
场景一:对服务的特定端口配置全局限流
对httpbin服务的8000端口进行限流。配置限流规则后,发往httpbin服务8000端口的所有请求都将受到流量速率限制。
使用以下内容,创建global-ratelimit-svc.yaml。
部分字段说明如下。关于字段的更多信息,请参见ASMGlobalRateLimiter CRD说明。
字段
说明
workloadSelector
用于匹配限流生效的工作负载。本场景中全局限流生效于httpbin服务的工作负载,设置为
app: httpbin
。isGateway
是否作用于网关。本示例中设定为
false
。rateLimitService
限流服务的域名、端口和连接超时设置。根据场景一:对服务的特定端口配置全局限流中部署的限流服务,配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
需要生效的限流配置参数。其中
unit
表示限流检测的时间单位,quota
表示单位时间内允许的请求总量。本示例配置
unit
为MINUTE
、quota
为1
,表示匹配路由上每分钟只能发送一个请求,超出的请求将被限流。vhost
限流匹配的域名和路由项配置。在生效于应用服务时,
name
需要填写为'*'
,port
需要填写为服务的Service端口。在ASM实例对应的KubeConfig环境下,执行以下命令,创建生效于应用服务httpbin入口流量的全局限流规则。
kubectl apply -f global-ratelimit-svc.yaml
执行以下命令,获取调谐完成的全局限流规则配置内容。
kubectl get asmglobalratelimiter global-svc-test -o yaml
将上一步预期输出的ASMGlobalRateLimiter资源中
status
字段的config.yaml
内容,粘贴至ratelimit-config.yaml,生成全局限流服务配置。ASMGlobalRateLimiter中
status
字段下的config.yaml
字段中的字符串内容,需原样粘贴至ConfigMap中data
中的同名config.yaml
字段中。在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中更新全局限流服务配置。
kubectl apply -f ratelimit-config.yaml
执行以下命令,进入sleep应用开启bash。
kubectl exec -it deploy/sleep -- sh
执行以下命令,连续访问httpbin服务两次。
curl httpbin:8000/get -v curl httpbin:8000/get -v
预期输出:
< HTTP/1.1 429 < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 5 < date: Thu, 26 Oct 2023 04:23:54 GMT < server: envoy < content-length: 0 < x-envoy-upstream-service-time: 2 < * Connection #0 to host httpbin left intact
在全局限流配置中,限制1分钟之内只能有一次访问httpbin服务的请求。当连续两次访问httpbin服务时,可以看到第二条请求被限流,表明对注入Sidecar的应用服务入口流量配置全局限流成功。
场景二:在服务特定端口上,针对发往指定路径的请求进行限流
对httpbin服务的8000端口进行限流,并限制限流只生效在访问/headers
路径的请求上。配置限流规则后,发往httpbin服务8000端口、且访问路径/headers
的所有请求都将受到流量速率限制。
根据ASM版本,按需选择以下内容,创建global-ratelimit-svc.yaml。
ASM版本为1.19.0以下:
ASM版本为1.19.0及以上:
部分字段说明如下。关于字段的更多信息,请参见ASMGlobalRateLimiter CRD说明。
字段
说明
workloadSelector
用于匹配限流生效的工作负载。本场景中全局限流生效于httpbin服务的工作负载,设置为
app: httpbin
。isGateway
是否作用于网关。本示例设定为
false
。rateLimitService
限流服务的域名、端口和连接超时设置。根据场景二:在服务特定端口上,针对发往指定路径的请求进行限流中部署的限流服务,配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
需要生效的限流配置参数。其中
unit
表示限流检测的时间单位,quota
表示单位时间内允许的请求总量。本示例配置
unit
为MINUTE
、quota
为1
,表示匹配路由上每分钟只能发送一个请求,超出的请求将被限流。在ASM实例为1.19.0及以上版本,限流配置参数为每秒100000个请求,约等于没有限流,因为针对满足特定条件请求的限流生效在
limit_overrides
字段中。vhost
限流匹配的域名和路由项配置。在生效于应用服务时,
name
需要填写为'*'
,port
需要填写为服务的Service端口。在ASM实例为1.19.0以下版本,您还可以在
route
中配置针对请求的Header匹配规则。本示例中匹配名为:path
的特殊Header,即匹配请求的路径,语义为匹配所有路径以/
开头的请求。在ASM实例为1.19.0及以上版本,在
route
中配置针对请求的Header匹配规则被移动到limit_overrides
字段中。
limit_overrides
限流覆盖配置,仅支持ASM实例为1.19.0及以上版本。支持匹配请求的不同属性,并对匹配到的特定请求应用单独的限流配置。在本示例中,
limit_overrides
字段里指定了匹配特殊的Header:path
,即匹配请求的路径,语义为匹配所有路径以/headers
开头的请求。
在ASM实例对应的KubeConfig环境下,执行以下命令,创建生效于应用服务httpbin入口流量的全局限流规则。
kubectl apply -f global-ratelimit-svc.yaml
执行以下命令,获取调谐完成的全局限流规则配置内容。
kubectl get asmglobalratelimiter global-svc-test -o yaml
将上一步预期输出的ASMGlobalRateLimiter资源中
status
字段的config.yaml
内容,粘贴至ratelimit-config.yaml,生成全局限流服务配置。ASMGlobalRateLimiter中
status
字段下的config.yaml
字段中的字符串内容,需原样粘贴至ConfigMap中data
中的同名config.yaml
字段中。在ACK集群对应的KubeConfig环境下,执行以下命令,在集群中更新全局限流服务配置。
kubectl apply -f ratelimit-config.yaml
执行以下命令,进入sleep应用开启bash。
kubectl exec -it deploy/sleep -- sh
执行以下命令,连续访问httpbin服务的
/headers
路径两次。curl httpbin:8000/headers -v curl httpbin:8000/headers -v
预期输出:
< HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 5 < date: Thu, 26 Oct 2023 04:23:54 GMT < server: envoy < content-length: 0 < x-envoy-upstream-service-time: 2 < * Connection #0 to host httpbin left intact
在全局限流配置中,限制在
/headers
路径上,1分钟之内只能有一次访问httpbin服务的请求。当连续两次访问httpbin服务的/headers路径时,可以看到第二条请求被限流,表明对注入Sidecar的应用服务入口流量配置全局限流成功。执行以下命令,访问httpbin服务的
/get
路径。curl httpbin:8000/get -v
可以看到发往httpbin服务其它路径的请求并未受到全局限流配置的影响,仍然可以正常访问。
相关操作
查看全局限流相关指标
全局限流会产生以下指标:
指标 | 指标类型 | 描述 |
envoy_cluster_ratelimit_ok | Counter | 被全局限流服务放行的请求总数 |
envoy_cluster_ratelimit_over_limit | Counter | 被全局限流服务判定为触发限流的请求总数 |
envoy_cluster_ratelimit_error | Counter | 调用全局限流服务失败的请求总数 |
您可以通过配置Sidecar代理的proxyStatsMatcher使Sidecar代理上报相关指标,然后使用Prometheus采集并查看限流相关指标。
通过proxyStatsMatcher配置Sidecar代理上报限流指标。在配置proxyStatsMatcher时,选中正则匹配,配置为
.*ratelimit.*
。具体操作,请参见proxyStatsMatcher。重新部署httpbin服务。具体操作,请参见重新部署工作负载。
参照场景一或在流量管理中心配置本地限流,完成本地限流配置及请求访问。
执行以下命令,查看httpbin服务的全局限流相关指标。
kubectl exec -it deploy/httpbin -c istio-proxy -- curl localhost:15090/stats/prometheus|grep envoy_cluster_ratelimit
预期输出:
# TYPE envoy_cluster_ratelimit_ok counter envoy_cluster_ratelimit_ok{cluster_name="inbound|80||"} 904 # TYPE envoy_cluster_ratelimit_over_limit counter envoy_cluster_ratelimit_over_limit{cluster_name="inbound|80||"} 3223
配置全局限流指标采集和告警
您可以配置Prometheus实例采集网格代理暴露的全局限流相关指标,并基于关键指标配置告警规则,实现限流发生时的及时告警。本文以可观测监控Prometheus版为例说明如何配置全局限流指标采集和告警。
在可观测监控Prometheus版中,为数据面集群接入阿里云ASM组件或升级至最新版,以保证可观测监控Prometheus版可以采集到暴露的全局限流指标。关于接入组件的具体操作,请参见接入组件管理。(如果您已经集成自建Prometheus实现网格监控来采集服务网格指标,则无需做额外操作。)
创建针对全局限流的告警规则。具体操作,请参见通过自定义PromQL创建Prometheus告警规则。配置告警规则的关键参数的填写示例如下,其余参数可参考上述文档根据实际需求填写。
参数
示例
说明
自定义PromQL语句
(sum by(namespace, service_istio_io_canonical_name) (increase(envoy_cluster_ratelimit_over_limit[1m]))) > 0
通过increase查询最近1分钟之内被限流的请求数量,并根据触发限流的服务所在命名空间以及服务名称进行分组。当1分钟内被限流的请求数量大于0时触发告警。
告警内容
发生全局限流!命名空间:{{$labels.namespace}},触发限流的服务:{{$labels.service_istio_io_canonical_name}}。当前1分钟内被限流的请求数量:{{ $value }}
示例的告警信息展示了触发限流的服务所在命名空间以及服务名称,以及最近1分钟内发往该服务被限流的请求数量。
相关文档
关于ASMGlobalRateLimiter的字段说明,请参见ASMGlobalRateLimiter CRD说明。
关于如何在流量管理中心配置本地限流,请参见在流量管理中心配置本地限流。
关于如何为ASM网关配置全局限流,请参见为入口网关配置全局限流。