ASM流量調度套件提供了精細化的限流策略,可以實現對進入指定服務的流量進行全域限流、分使用者限流、設定突發流量視窗、自訂請求token消耗速率等進階限流功能。本文介紹如何使用流量調度套件提供的RateLimitingPolicy來支援分使用者限流情境。
背景資訊
ASM流量調度套件的限流策略採用令牌桶演算法。系統以固定速率產生令牌(tokens),並加入到令牌桶中,直到容量上限。服務間的請求需要消耗tokens才能發送成功,如果桶中有足夠的tokens,請求發送時將消耗token;如果沒有足夠的tokens,請求可能會被排隊或丟棄。此演算法可以保證資料轉送的平均速率不會超過token的產生速率,同時又能應對一定程度的突發流量。
前提條件
已添加Kubernetes託管版叢集到ASM執行個體,且ASM執行個體為1.21.6.83版本及以上。具體操作,請參見添加叢集到ASM執行個體。
已通過kubectl串連至ACK叢集。 具體操作,請參見擷取叢集KubeConfig並通過kubectl工具串連叢集。
已開啟ASM流量調度套件。具體操作,請參見開啟ASM流量調度套件。
已為Kubernetes叢集中的default命名空間開啟自動注入。具體操作,請參見管理全域命名空間。
已建立名為ingressgateway的入口網關,並開啟80連接埠。具體操作,請參見建立入口網關。
準備工作
部署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應用Pod。
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,表明訪問成功。
步驟一:建立RateLimitingPolicy限流規則
使用kubectl串連到ASM執行個體,具體操作,請參見通過控制面kubectl訪問Istio資源。
使用以下內容,建立ratelimitingpolicy.yaml檔案。
apiVersion: istio.alibabacloud.com/v1 kind: RateLimitingPolicy metadata: name: ratelimit namespace: istio-system spec: rate_limiter: bucket_capacity: 2 fill_amount: 2 parameters: interval: 30s limit_by_label_key: http.request.header.user_id selectors: - agent_group: default control_point: ingress service: httpbin.default.svc.cluster.local
部分欄位說明如下。關於欄位的更多資訊,請參見RateLimitingPolicy CRD說明。
欄位
說明
fill_amount
在interval指定的時間間隔內填充令牌的數量。樣本中指定為2,即每過interval指定的時間間隔後便向令牌桶填充2個令牌。
interval
向令牌桶中填充令牌的時間間隔。樣本中指定為30s,即每過30秒後便向令牌桶填充2個令牌。
bucket_capacity
令牌桶內的令牌數量上限。當請求速率小於令牌桶填充速率時,令牌桶內的令牌數量會持續增加,最大將達到
bucket_capacity
。使用bucket_capacity
可以容許一定程度的突發流量。樣本中設定為2,和fill_amount相同,即不允許任何突發流量。limit_by_label_key
指定限流策略使用什麼請求標籤進行分組,指定後,不同標籤的請求將分別進行限流,擁有相互獨立的令牌桶。樣本中使用
http.request.header.user_id
,其意義是使用請求的user_id
要求標頭進行分組,類比了分使用者限流的情境。樣本中假設不同的使用者發起的請求擁有不同的used_id
要求標頭。selectors
指定應用限流策略的多個服務。樣本中使用
service: httpbin.default.svc.cluster.local
表示對httpbin.default.svc.cluster.local
服務進行限流。
執行以下命令,建立RateLimitingPolicy限流規則
kubectl apply -f ratelimitingpolicy.yaml
步驟二:驗證分使用者限流效果
使用ACK叢集的kubectl執行以下命令,進入sleep應用開啟bash。
kubectl exec -it deploy/sleep -- sh
執行以下命令,使用user1身份連續訪問httpbin服務的/headers路徑兩次。
curl -H "user_id: user1" httpbin:8000/headers -v curl -H "user_id: user1" httpbin:8000/headers -v
預期輸出:
< HTTP/1.1 429 Too Many Requests < retry-after: 14 < date: Mon, 17 Jun 2024 11:48:53 GMT < server: envoy < content-length: 0 < x-envoy-upstream-service-time: 1 < * Connection #0 to host httpbin left intact
在第2步執行後的30秒內,執行以下命令,使用user2身份訪問httpbin服務的/headers路徑一次。
curl -H "user_id: user2" httpbin:8000/headers -v
預期輸出:
< HTTP/1.1 200 OK < server: envoy < date: Mon, 17 Jun 2024 12:42:17 GMT < content-type: application/json < content-length: 378 < access-control-allow-origin: * < access-control-allow-credentials: true < x-envoy-upstream-service-time: 5 < { "headers": { "Accept": "*/*", "Host": "httpbin:8000", "User-Agent": "curl/8.1.2", "User-Id": "user2", "X-Envoy-Attempt-Count": "1", "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=ddab183a1502e5ededa933f83e90d3d5266e2ddf87555fb3da1ad40dde3c722e;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep" } } * Connection #0 to host httpbin left intact
可以看到user2訪問相同的路徑並未觸發限流,證明分使用者限流成功。
相關操作
您可以通過Grafana大盤來觀測RateLimitingPolicy策略的執行效果。請確保Grafana使用的資料來源Prometheus執行個體已經完成配置採集ASM流量調度套件相關指標。
將以下內容匯入到Grafana,建立RateLimitingPolicy策略的大盤。
大盤效果如下。