限流是一種限制發送到服務端的請求數量的機制。它指定用戶端在給定時間段內可以向服務端發送的最大請求數,通常表示為一段時間內的請求數,例如每分鐘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網關配置全域限流,請參見為入口網關配置全域限流。