在面临高流量冲击、服务过载、资源耗尽或恶意攻击的情况下,通过配置限流防护,可以实现对流量的精准控制,从而保护后端服务的稳定性,降低成本并提升用户体验。服务网格ASM提供了本地限流与全局限流两种方式,提供基于服务网格的无侵入式应用限流防护手段。详情请参考:https://help.aliyun.com/zh/asm/user-guide/current-limiting-protection。
在参考上述一系列文档、为网关或集群内服务配置了本地限流或全局限流后,网关或Sidecar代理将产生限流相关的指标。我们可以配置使用Prometheus采集这些指标、以及设定相关告警规则,帮助我们观测限流相关事件。本文以使用阿里云服务网格ASM和阿里云可观测监控Prometheus版为例,简要展示如何利用限流相关指标。
一、配置暴露限流相关指标
envoy作为istio的数据面代理,在实现请求代理与编排的同时,提供了丰富的监控指标。但出于效率考虑,istio并没有默认暴露全部的相关指标,而限流相关的指标也属于此列。
对于这些指标,我们要使用proxyStatsMatcher对其进行暴露。
在envoy中,本地限流与全局限流分别暴露不同的一组指标:
对于本地限流,可参考使用这些指标——
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)。 |
对于全局限流,则主要使用这些指标——
Metric | 描述 |
---|---|
envoy_cluster_ratelimit_ok | 被全局限流服务放行的请求总数 |
envoy_cluster_ratelimit_over_limit | 被全局限流服务判定为触发限流的请求总数 |
envoy_cluster_ratelimit_error | 调用全局限流服务失败的请求总数 |
所有这些指标都是Counter类型。其中,本地限流相关指标可以用正则表达式.*http_local_rate_limit.*
来匹配到,全局限流相关指标可以用正则表达式.*ratelimit.*
匹配到。
1、配置Sidecar代理暴露限流指标
在服务网格ASM中,可以使用Sidecar代理配置功能为Sidecar代理加入proxyStatsMatcher,具体可以参考proxyStatsMatcher来在ASM控制台上进行操作。在proxyStatsMatcher中,我们可以选择正则匹配,加入对于限流指标的匹配正则表达式,下方是一个示例配置截图。
在Sidecar代理配置中配置了proxyStatsMatcher后,需要重新部署pod生效。此时,Sidecar代理就会开始对外暴露限流相关指标。
2、ASM网关暴露限流指标
对于ASM网关,则需要使用pod annotation的方式为网关加入proxyStatsMatcher:
- 登录ASM控制台,在左侧导航栏,选择服务网格 > 网格管理。
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择ASM网关 > 入口网关。
- 在入口网关页面右侧,单击目标网关对应的查看YAML,在编辑对话框的spec字段下,配置podAnnotations,然后单击确定。
注意:上述操作会导致网关重启。podAnnotations: proxy.istio.io/config: | proxyStatsMatcher: inclusionRegexps: - ".*http_local_rate_limit.*" - ".*ratelimit.*"
二、配置Prometheus采集envoy指标
在数据平面Kubernetes集群对应的Prometheus实例中,可以通过配置scrap_configs的方式来采集这些暴露的指标。本文以数据平面使用阿里云ACK集群,集成阿里云可观测监控Prometheus版为例。
当前,我们可以通过添加自定义的服务发现规则来采集envoy暴露的指标。我们可以参考管理自定义服务发现这篇文档的说明。在自定义服务发现配置处,可以填写以下参考配置:
- job_name: envoy-stats
honor_timestamps: true
scrape_interval: 30s
scrape_timeout: 30s
metrics_path: /stats/prometheus
scheme: http
follow_redirects: true
relabel_configs:
- source_labels: [__meta_kubernetes_pod_container_port_name]
separator: ;
regex: .*-envoy-prom
replacement: $1
action: keep
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
separator: ;
regex: ([^:]+)(?::\d+)?;(\d+)
target_label: __address__
replacement: $1:15090
action: replace
- {
separator: ;, regex: __meta_kubernetes_pod_label_(.+), replacement: $1, action: labelmap}
- source_labels: [__meta_kubernetes_namespace]
separator: ;
regex: (.*)
target_label: namespace
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_pod_name]
separator: ;
regex: (.*)
target_label: pod_name
replacement: $1
action: replace
metric_relabel_configs:
- source_labels: [__name__]
separator: ;
regex: istio_.*
replacement: $1
action: drop
kubernetes_sd_configs:
- {
role: pod, follow_redirects: true}
上述配置会通过envoy 的 http-envoy-prom(15090)端口对指标进行采集,并抛弃掉istio开头的若干指标(这些指标已经由ASM指标监控默认集成)。
一段时间后,在ARMS控制台的服务发现处,应该可以找到envoy-stats这个job采集到的限流相关指标:
三、利用限流指标配置告警
当Prometheus实例采集到相关指标后,就可以利用这些指标配置一些告警规则。以阿里云可观测监控Prometheus版为例,我们可以参考通过自定义PromQL创建Prometheus告警规则来进行配置。
配置告警规则时,我们需要根据具体需求来配置PromQL。限流相关的指标均为Counter类型,我们可以配置一些我们关心的指标的增长情况。
比如,对于本地限流来说,envoy_http_local_rate_limiter_http_local_rate_limit_enforced代表最终收到限流响应的请求总数,可能是一个收到更多关心的指标。我们可以配置这样的自定义promQL作为告警规则。
increase(envoy_http_local_rate_limiter_http_local_rate_limit_enforced[5m]) > 10
这代表在5分钟之内,被限流的请求数量超过了10,此时我们想要触发告警(实际数字需要根据具体业务指标调整)。
对于全局限流来说,类似语义的指标是envoy_cluster_ratelimit_over_limit,也可以类似地通过promQL来触发告警。