在大促等場景下,瞬間洪峰流量會使系統超出最大負載,調用大量堆積,導致整個調用鏈路卡死。ASM提供了本地限流功能,支持對網關進行流量限制,達到保護系統的目的。本文介紹如何為入口網關配置本地限流。
前提條件
已創建ASM實例,且ASM實例要符合以下要求:
ASM商業版(專業版或旗艦版):版本需為1.11.5.30及以上。關于升級ASM實例的具體操作,請參見升級ASM實例。
ASM標準版:僅支持Istio原生方式配置本地限流功能,且版本需為1.9及以上。不同Istio版本需參考相應版本文檔,關于最新的Istio版本配置本地限流功能的具體操作,請參見Enabling Rate Limits using Envoy。
已添加集群到ASM實例。具體操作,請參見添加集群到ASM實例。
已部署入口網關。具體操作,請參見創建入口網關。
已創建bookinfo和nginx服務。本文將bookinfo部署在default命名空間,將nginx部署在foo命名空間。創建bookinfo的具體操作,請參見在ASM實例關聯的集群中部署應用。
使用以下內容,創建nginx.yaml。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx sidecarset-injected: "true" spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: ClusterIP
執行以下命令,在foo命名空間部署Nginx。
kubectl apply -f nginx.yaml -n foo
已創建網關規則和虛擬服務。具體操作,請參見管理網關規則和管理虛擬服務。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: bookinfo-gateway namespace: default spec: selector: istio: ingressgateway servers: - hosts: - bf2.example.com port: name: http number: 80 protocol: http
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: bookinfo namespace: default spec: gateways: - bookinfo-gateway hosts: - bf2.example.com http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products name: productpage-route-name1 route: - destination: host: productpage port: number: 9080 - match: - uri: prefix: /nginx name: nginx-route-name1 rewrite: uri: / route: - destination: host: nginx.foo.svc.cluster.local port: number: 80
已安裝流量加壓工具。具體操作,請參見hey。
適用對象
ASM本地限流功能適用于ASM網關和應用服務(注入了Sidecar)。
場景示例說明
本文以Bookinfo和Nginx為例介紹網關和服務限流的具體使用場景。Nginx將單獨部署在foo命名空間,用于驗證限流的開啟范圍。
場景一:對單個虛擬服務路由配置限流規則
對bf2.example.com:80
這個域名和端口組合下的productpage-route-name1路由配置限流規則。productpage-route-name1是前提條件中創建的虛擬服務bookinfo中的一條路由項,匹配了請求的/productpage
、/static
、/login
、/logout
等路徑并將匹配的請求轉發到productpage服務。配置限流規則后,發往上述路徑的請求都將受到流量速率的限制。
創建本地限流規則。
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 ,然后單擊創建。
在創建頁面,按需進行以下配置,然后單擊確定。
關于配置項的詳情,請參見ASMLocalRateLimiter CRD說明。
配置區域
配置項
說明
限流基本信息
命名空間
本地限流配置的命名空間,需要配置為限流生效的工作負載的所在命名空間。本示例必須選擇istio-system,因為所有ASM網關都部署在istio-system命名空間。
名稱
本地限流配置的自定義名稱。本示例填寫ingressgateway。
生效工作負載類型
限流生效的工作負載類型,支持應用服務生效和網關生效。本示例選擇網關生效。
關聯工作負載
在生效工作負載類型為網關生效的情況下,可以通過選擇網關規則的方式關聯工作負載,本地限流配置將與選中的網關規則關聯相同的網關工作負載。本示例選擇bookinfo-gateway。
限流規則列表
網關域名
選擇網關規則中聲明的域名,限流規則將在指定的端口和域名組合下生效。本示例選擇bf2.example.com。
網關端口
選擇網關規則中聲明的端口,限流規則將在指定的端口和域名組合下生效。本示例選擇80。
匹配虛擬服務路由項
選擇與網關規則關聯的虛擬服務中聲明的路由項。限流規則將在指定的虛擬服務路由項之下生效。本示例選擇productpage-route-name1。
限流配置
指定本地限流令牌桶算法的檢測時間窗口長度與時間窗口內允許的請求數量。在時間窗口內發送的請求數量超過該允許的數量則會對請求進行限流。本示例配置如下:
限流檢測時間窗口填寫1秒。
時間窗口內允許請求數量填寫10。
以上配置表示發往此服務的工作負載的請求不得在1秒內連續發送10個以上。
高級選項
單擊展開高級選項,可以指定限流發生時的部分高級行為。您可按需對高級選項進行配置。本示例自定義限流響應體填寫
{"ret_code": xxx,"message": "Your request be limited"}
。以上配置對應的本地限流配置YAML如下。
如果您沒有配置高級選項,限流時將返回默認響應信息。
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMLocalRateLimiter metadata: name: ingressgateway namespace: istio-system spec: configs: - limit: fill_interval: seconds: 1 quota: 10 match: vhost: name: bf2.example.com port: 80 route: name_match: productpage-route-name1 isGateway: true workloadSelector: labels: istio: ingressgateway
如果您配置了高級選項,限流時將返回自定義響應信息。
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMLocalRateLimiter metadata: name: ingressgateway namespace: istio-system spec: configs: - limit: custom_response_body: '{"ret_code": xxx, "message": "Your request be limited" }' fill_interval: seconds: 1 quota: 10 match: vhost: name: bf2.example.com port: 80 route: name_match: productpage-route-name1 isGateway: true workloadSelector: labels: istio: ingressgateway
在hey工具中執行以下命令,持續產生壓力流量。
hey -host bf2.example.com -c 10 -n 100000 http://<ASM網關IP>/productpage
hey -host bf2.example.com -c 10 -n 100000 http://<ASM網關IP>/nginx
執行以下命令,訪問網關的/productpage路徑。
curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v
預期輸出:
< HTTP/1.1 429 Too Many Requests < Content-Length: 18 < Content-Type: text/plain < Date: Thu, 13 Jan 2022 03:03:09 GMT < Server: istio-envoy < local_rate_limited
可以看到訪問bookinfo服務受到限流。
執行以下命令,訪問網關的/nginx路徑。
curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/nginx -v
返回結果中沒有429,說明訪問未限流。
場景二:對網關上域名和端口的組合限流規則
對bf2.example.com:80
這個域名和端口組合設定限流配置,使該域名和端口組合下的所有路徑都受到流量限制。
配置限流規則。
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 ,然后單擊創建。
在創建頁面,按需進行以下配置,然后單擊確定。
關于配置項的詳情,請參見ASMLocalRateLimiter CRD說明。
配置區域
配置項
說明
限流基本信息
命名空間
本地限流配置的命名空間,需要配置為限流生效的工作負載的所在命名空間。本示例必須選擇istio-system,因為所有ASM網關都部署在istio-system命名空間。
名稱
本地限流配置的自定義名稱。本示例填寫ingressgateway。
生效工作負載類型
限流生效的工作負載類型,支持應用服務生效和網關生效。本示例選擇網關生效。
關聯工作負載
在生效工作負載類型為網關生效的情況下,可以通過選擇網關規則的方式關聯工作負載,本地限流配置將與選中的網關規則關聯相同的網關工作負載。本示例選擇bookinfo-gateway。
限流規則列表
網關域名
選擇網關規則中聲明的域名,限流規則將在指定的端口和域名組合下生效。本示例選擇bf2.example.com。
網關端口
選擇網關規則中聲明的端口,限流規則將在指定的端口和域名組合下生效。本示例選擇80。
匹配虛擬服務路由項
選擇與網關規則關聯的虛擬服務中聲明的路由項。限流規則將在指定的虛擬服務路由項之下生效。本示例不進行選擇,表示在域名和端口下的所有路由項上都生效限流規則。
限流配置
指定本地限流令牌桶算法的檢測時間窗口長度與時間窗口內允許的請求數量。在時間窗口內發送的請求數量超過該允許的數量則會對請求進行限流。本示例配置如下:
限流檢測時間窗口填寫1秒。
時間窗口內允許請求數量填寫10。
以上配置表示發往此服務的工作負載的請求不得在1秒內連續發送10個以上。
以上配置對應的本地限流配置YAML如下。
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMLocalRateLimiter metadata: name: ingressgateway namespace: istio-system spec: configs: - limit: fill_interval: seconds: 1 quota: 10 match: vhost: name: bf2.example.com port: 80 route: {} isGateway: true workloadSelector: labels: istio: ingressgateway
在hey工具中執行以下命令,持續產生壓力流量。
hey -host bf2.example.com -c 10 -n 100000 http://${ASM_GATEWAY_IP}/nginx
執行以下命令,訪問網關的/nginx路徑。
curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/nginx -v
可以看到,返回
HTTP/1.1 429 Too Many Requests
,說明訪問網關上的/nginx路徑受到限流。
場景三:在單個虛擬服務路由上,針對包含特定請求頭的請求配置限流規則
對bf2.example.com:80
這個域名和端口組合下的nginx-route-name1路由配置限流規則,同時指定限流規則只生效在帶有ratelimit: "true"
請求頭的請求上,該路由上的其他請求不受限流規則影響。nginx-route-name1是前提條件中創建的虛擬服務bookinfo中的一條路由項,匹配了請求的/nginx
路徑并將匹配的請求轉發到nginx服務。
配置限流規則。
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 ,然后單擊創建。
在創建頁面,按需進行以下配置,然后單擊確定。
關于配置項的詳情,請參見ASMLocalRateLimiter CRD說明。
配置區域
配置項
說明
限流基本信息
命名空間
本地限流配置的命名空間,需要配置為限流生效的工作負載的所在命名空間。本示例必須選擇istio-system,因為所有ASM網關都部署在istio-system命名空間。
名稱
本地限流配置的自定義名稱。本示例填寫ingressgateway。
生效工作負載類型
限流生效的工作負載類型,支持應用服務生效和網關生效。本示例選擇網關生效。
關聯工作負載
在生效工作負載類型為網關生效的情況下,可以通過選擇網關規則的方式關聯工作負載,本地限流配置將與選中的網關規則關聯相同的網關工作負載。本示例選擇bookinfo-gateway。
限流規則列表
網關域名
選擇網關規則中聲明的域名,限流規則將在指定的端口和域名組合下生效。本示例選擇bf2.example.com。
網關端口
選擇網關規則中聲明的端口,限流規則將在指定的端口和域名組合下生效。本示例選擇80。
匹配虛擬服務路由項
選擇與網關規則關聯的虛擬服務中聲明的路由項。限流規則將在指定的虛擬服務路由項之下生效。本示例選擇路由項nginx-route-name1。
匹配請求屬性
填寫生效限流配置的具體請求匹配規則。本示例配置如下:
匹配屬性選擇具體請求頭。
請求頭名稱填寫ratelimit。
匹配方法選擇精確匹配。
匹配內容填寫true。
限流配置
指定本地限流令牌桶算法的檢測時間窗口長度與時間窗口內允許的請求數量。在時間窗口內發送的請求數量超過該允許的數量則會對請求進行限流。本示例配置如下:
限流檢測時間窗口填寫1秒。
時間窗口內允許請求數量填寫10。
以上配置表示發往此服務的工作負載的請求不得在1秒內連續發送10個以上。
以上配置對應的本地限流配置YAML如下。
apiVersion: istio.alibabacloud.com/v1 kind: ASMLocalRateLimiter metadata: name: ingressgateway namespace: istio-system spec: configs: - limit: fill_interval: seconds: 1 quota: 10 match: vhost: name: bf2.example.com port: 80 route: header_match: - exact_match: 'true' invert_match: false name: ratelimit name_match: nginx-route-name1 isGateway: true workloadSelector: labels: istio: ingressgateway
在hey工具中執行以下命令,持續產生壓力流量,請求都攜帶
ratelimit: true
的請求頭以觸發限流。hey -host bf2.example.com -H 'ratelimit: true' -c 10 -n 10000 http://${ASM_GATEWAY_IP}/nginx
執行以下命令,訪問網關的
/nginx
路徑。curl -H 'host: bf2.example.com' -H 'ratelimit: true' http://${ASM_GATEWAY_IP}/nginx -v
可以看到返回
HTTP/1.1 429 Too Many Requests
,說明訪問網關/nginx
路徑、并攜帶ratelimit: true
請求頭的請求受到了限流。執行以下命令,訪問網關的
/nginx
路徑,但請求不攜帶ratelimit: true
請求頭。curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/nginx -v
可以看到返回結果中沒有429,說明未攜帶
ratelimit: true
請求頭的請求未受限流影響。
相關操作
刪除限流配置,恢復訪問
刪除限流規則。
登錄ASM控制臺,在左側導航欄,選擇 。
在網格管理頁面,單擊目標實例名稱,然后在左側導航欄,選擇 。
在限流防護頁面的操作列,單擊目標限流規則對應的刪除,在確認對話框,單擊確定。
執行以下命令,訪問網關的
/nginx
路徑。curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/nginx -v
返回結果中沒有429,說明訪問未限流。