全部產品
Search
文件中心

API Gateway:流量控制外掛程式

更新時間:Jul 13, 2024

本文介紹了流量控制外掛程式的配置及常見情境樣本。

1. 概述

  • 流量控制外掛程式用於對API進行限流,流量控制外掛程式可以對APIApp(訪問的AK)使用者(訪問方的App歸屬使用者),以及自訂參數進行多種維度限流。

  • 流量控制外掛程式目前支援兩種配置模板:

    • 參數流控配置,支援自訂參數的流控配置。

    • 基礎流控配置,與控制台上的流量控制功能保持相容。

  • 流量控制現在合并進了外掛程式體系。現存的流量控制介面與介面仍然可以使用,流量控制策略流量控制外掛程式屬於同一種外掛程式類型,如果你綁定了流量控制外掛程式,則流量控制策略會失效

  • 使用原有的流量控制介面或控制台建立或更改流量控制,會同步資料至外掛程式系統,但不會反向同步。

2. 基礎流控配置

2.1. 流控能力

2.1.1 基礎流控支援以下的流控維度:

  • API 流量限制:該策略綁定的API在單位時間內被調用的次數不能超過設定值,單位時間可選秒、分鐘、小時、天,如5000次/分鐘。

  • APP 流量限制:每個App對該策略綁定的任何一個API在單位時間內的調用次數不能超過設定值。如50000次/小時。

  • 使用者流量限制:每個阿里雲帳號對該策略綁定的任何一個 API 在單位時間內的調用次數不能超過設定值。一個阿里雲帳號可能有多個 APP,所以對阿里雲帳號的流量限制就是對該帳號下所有 APP 的流量總和的限制。如 50 萬次/天。

說明

在一個流控策略外掛程式裡面,這三個值可以同時設定。請注意,使用者流量限制應不大於 API 流量限制,APP 流量限制應不大於使用者流量限制。即 APP 流量限制 <= 使用者流量限制 <= API 流量限制。

此外,您可以在流控策略下添加特殊應用(APP)和特殊使用者。對於特例,流控策略基礎的API 流量限制依然有效,您需要額外設定一個閾值作為該 APP 或者該使用者的流量限制值,該值不能超過策略的API流量限制值,同時流控策略基礎的APP流量限制使用者流量限制對該 APP 或使用者失效。

2.1.2 流控外掛程式支援的時間維度及其演算法

API Gateway流控外掛程式支援的時間維度分別是秒(SENCOND)、分鐘(MINUTE)、小時(HOUR)、天(DAY)。其中分鐘、小時、天維度使用的是固定時間視窗演算法。秒層級預設使用的是令牌桶流控演算法,若不滿足需求,可以配置固定時間視窗流控演算法。兩種演算法分別如下:

  • 令牌桶流控演算法:秒層級的流控預設用的是令牌桶演算法。令牌桶演算法有兩個概念,令牌桶和一個Waiting Queue。API Gateway的引擎會定期向令牌桶發放令牌,用戶端發送的請求進到API Gateway後會先去令牌桶裡取令牌,取到令牌就通過了。如果沒有取到令牌,請求會進一個Queue中排隊,下一波發令牌的時候優先分配給Queue中請求。Queue滿了之後,請求再進來就會報429;如果不想進入Queue排隊,可以直接配置blockingMode: QUICK_RETURN,就不會進入Queue排隊,如果沒有取到令牌,直接報錯429。

  • 固定時間視窗流控演算法:限制單位時間的流量,例如限制每分鐘1000次請求,超過部分報429,下一分鐘重設請求計數。

2.2. 基礎流控外掛程式配置

可以選擇JSON或者YAML格式的來配置您的外掛程式,兩種格式的schema相同,可以搜尋yaml to json轉換工具來進行配置格式的轉換,yaml格式的模板見下表。

---
unit: SECOND         # 控制區間, 取值: SECOND, MINUTE, HOUR, DAY
apiDefault: 1000     # 允許的總流量值
controlMode: FIX_WINDOW  # 當時間維度為秒時,指定流控演算法為固定時間視窗演算法
blockingMode: QUICK_RETURN     #令牌桶流控演算法時,不會進入Queue排隊,如果沒有取到令牌,直接報429
userDefault: 30      # (可選)每個使用者的預設流量最大值, 0表示不進行限制, 不能大於總流量值
appDefault: 30       # (可選)每個APP允許的流量最大值, 0表示不進行限制, 不能大於總流量值
specials:            # (可選)特殊流控, 支援"APP"和"USER"兩種特殊維度
  - type: "APP"      # 針對不同應用(AK)進行的流控
    policies:
    - key: 10123123  # AppId, AppId的取值請在API Gateway控制台->應用管理->應用詳情處查看
      value: 10      # 特殊流控值, 不能大於總流量值
    - key: 10123123  # AppId控
      value: 10      # 特殊流控值, 不能大於總流量值
  - type: "USER"     # 針對不同的阿里雲賬戶進行的流控
    policies:
    - key: 123455    # 阿里雲帳號ID, 可點擊阿里雲控制台左上方查看帳號ID
      value: 100     # 特殊流控值, 不能大於總流量值

2.3 基礎流控外掛程式支援外掛程式資料集

2.3.1 建立流控外掛程式資料集

  1. 登入API Gateway控制台,左側欄單擊開放API——外掛程式管理——自訂資料集

  2. 單擊右上方的建立資料集,在彈出框中自訂資料集的名稱,類型選擇TRAFFIC_CONTROL_POLICY,單擊確定即可產生資料集。

  3. 進入剛產生的資料集,單擊右上方的建立資料集條目,即可在頁面中配置流控外掛程式支援的key和value,其中,key為AppId或阿里雲帳號ID;value則是對應的流控值。

2.3.2 流控外掛程式配置外掛程式資料集樣本

基礎流控外掛程式支援使用外掛程式資料集,特殊流控specials策略可使用外掛程式資料集配置APP和流控值、使用者阿里雲帳號ID和流控值。樣本如下:

---
unit: SECOND         # 控制區間, 取值: SECOND, MINUTE, HOUR, DAY
apiDefault: 1000     # 允許的總流量值
userDefault: 30      # (可選)每個使用者的預設流量最大值, 0表示不進行限制, 不能大於總流量值
appDefault: 30       # (可選)每個APP允許的流量最大值, 0表示不進行限制, 不能大於總流量值
specials:            # (可選)特殊流控, 支援"APP"和"USER"兩種特殊維度
  - type: "APP"      # 針對不同應用(AK)進行的流控
    policyDatasetId: 87b65008e92541938XXXXXXXX6eda5		# 外掛程式資料集ID
    policies:
    - key: 10123123  # AppId, AppId的取值請在API Gateway控制台->應用管理->應用詳情處查看
      value: 10      # 特殊流控值, 不能大於總流量值
    - key: 10123123  # AppId控
      value: 10      # 特殊流控值, 不能大於總流量值
  - type: "USER"     # 針對不同的阿里雲賬戶進行的流控
    policyDatasetId: 87b65008eXXXXXXXXXXXXa236eda5		# 外掛程式資料集ID
    policies:
    - key: 123455    # 阿里雲帳號ID, 可點擊阿里雲控制台左上方查看帳號ID
      value: 100     # 特殊流控值, 不能大於總流量值
重要

本次開發只針對基礎配置模式的外掛程式格式進行外掛程式資料集的支援,對參數流控配置模式的外掛程式配置暫不進行外掛程式資料集的支援。

3. 參數流控配置

參數流控可以針對使用者的請求參數以及條件執行進行流控,參數流控配置支援如下特性:

  • 支援秒、分鐘、小時、天的流控維度

  • 可以根據請求參數、系統參數設定條件,來執行不同的流控維度

  • 可以使用單個參數、或多個參數的組合來設定流控

  • 可以設定流控的範圍為API或外掛程式

3.1. 快速開始

有這樣一個情境,我們希望執行如下的規則執行流控,針對每個訪問的用戶端IP地址,當使用者使用了AppId:10001的Key做了簽名認證時,設定流控為100請求/秒,對其他的場合為10請求/秒

針對這個情境我們的外掛程式配置如下,這裡我們使用yaml來配置外掛程式。

---
scope: "PLUGIN"
#
# 這個流控依賴兩個系統參數
# 1. 使用者簽名的AppId,通過系統參數CaAppId擷取
# 2. 使用者來源的ClientIP,通過系統參數CaClientIp擷取
parameters:
  AppId: "System: CaAppId"
  ClientIP: "System: CaClientIp"
rules:
  # 第一條流控策略,當`AppId`為`10001`時生效,對每個ClientIP限流為`100/秒`
  - name: "Vip"
    condition: "$AppId = 10001"
    byParameters: "ClientIP"
    value: 100
    period: SECOND
  # 第二條流控策略名稱為`PerClientIP`,對每個ClientIP限流為`10/秒`
  - name: "PerClientIP"
    byParameters: "ClientIP"
    bypassEmptyValue: true   #當rules中的規則沒有添加condition,以byParameters參數為判斷條件時,參數為空白或傳了空值此規則不生效,會走預設流控策略
    value: 10
    period: SECOND

3.2. 參數流控外掛程式配置

參數流控外掛程式使用yaml或等價的json格式進行外掛程式中繼資料配置。

---
scope: "PLUGIN"                # 流控外掛程式的作用範圍:目前可選為"PLUGIN", "API"
blockingMode: QUICK_RETURN     #不會進入Queue排隊,如果沒有取到令牌,直接報429,詳情可查看下面的欄位說明
controlMode: FIX_WINDOW  # 當時間維度為秒時,指定流控演算法為固定時間視窗演算法
defaultLimit: 100              # 預設流控值,如果設定了預設流控值
defaultPeriod: SECOND          # 預設流控周期
defaultRetryAfterBySecond: 60  #返回Retry-After標題,它提供建議在下一個請求之前需要等待多長時間
defaultErrorMessage: "Throttled by 100/SECOND"
parameters:                    # 參數列表, 可用於流控的參數
  clientIp: "System:CaClientIp"
  userId: "Token:userId"
rules:
  - name: "ByClientIp"
    byParameters: "clientIp"
    condition: "$clientIp !in_cidr '61.7.XX.XX/24'"
    limit: 10
    period: MINUTE
    retryAfterBySecond: 60    #返回Retry-After標題,它提供建議在下一個請求之前需要等待多長時間
    errorMessage: "Throttled by 10/MINUTE from ${clientIp}"
  - name: "每個使用者限制10條/分鐘,管理員除外"
    byParameters: "clientIp"
    condition: "$userId !like 'admin%'"
    limit: 10
    period: MINUTE
    retryAfterBySecond: 60    #返回Retry-After標題,它提供建議在下一個請求之前需要等待多長時間
  - name: "每個IP限制10條/分鐘"
    byParameters: "clientIp"
    condition: "$clientIp in_cidr '67.0.XX.XX/8'"
    limit: 10
    period: MINUTE
  - name: "每個使用者限制15條/分鐘"
    condition: "$userId !like 'admin%'"
    limit: 15
    period: MINUTE
    byParameters: "clientIp"

外掛程式配置的欄位說明如下:

  • scope(必選):流控外掛程式的作用範圍,支援APIPLUGIN兩種取值,如果多個API都綁定了同一個外掛程式,則scope的取值會影響流控策略的作用範圍,比如:某個策略取值為10次/秒

    • 當取值為API時:流控策略在每個API中分別生效,在本例子中,每個API的限流均為10次/秒

    • 當取值為PLUGIN時:所有綁定了本外掛程式的API共用這個限流,如果本例子中的外掛程式綁定了一堆API,則這一堆API的總流控限制為10次/秒

  • parameters(必選):參與流控的參數表,參考參數與條件運算式的使用文檔中的描述

  • rules(可選):流控策略的列表,如果沒有設定預設流控defaultLimitperiod, 則不可為空,每個流控策略包含以下欄位:

    • name(必選):流控策略的名稱,合法值為[A-Za-z0-9_-]+,在同一個外掛程式中保持唯一

    • byParameters(必選):流控參數,如果使用多個參數組合流控,以“,”分割,比如:ClientIP表示,針對每個ClientIP的取值分別進行流控,UserId,Action表示對這兩個參數的組合取值分別進行流控

    • bypassEmptyValue(可選):值為true時,當rules中的規則沒有添加condition,以byParameters參數為判斷條件時,參數為空白或傳了空值此規則不生效,會走預設流控策略

    • condition(可選):如果設定了條件,只有當條件符合時,才會執行此條流控策略

    • limit(必選):流控值,正整數,當為-1時表示當命中此條件時不需要流控

    • period(必選): 流控周期,取值:SECOND,MINUTE,HOUR,DAY

    • errorMessage(可選):定製錯誤資訊,可以以模板的方式來定義,在parameters中定義的參數,可以在${Name}的方式來配置

    • retryAfterBySecond(可選):返回Retry-After標題,它提供建議在下一個請求之前需要等待多長時間

  • defaultLimit(可選):預設流控值,正整數

  • defaultPeriod(可選):流控周期,取值: SECOND,MINUTE,HOUR,DAY

  • defaultErrorMessage(可選):定製錯誤資訊,當配置了定製的錯誤資訊後,返回的X-Ca-Error-Message頭會使用定製的錯誤資訊,這個資訊無法使用參數

  • defaultRetryAfterBySecond(可選):預設返回的Retry-After標題,它提供建議在下一個請求之前需要等待多長時間。

  • blockingMode(可選):API Gateway使用了標準的令牌桶演算法來實現流控功能,關於欄位值以及演算法詳情如下:

    • QUEUE(預設值):令牌桶演算法有兩個概念:令牌桶和一個Waiting Queue。API Gateway的引擎會定期向令牌桶發放令牌,用戶端發送的請求進到API Gateway後會先去令牌桶裡取令牌,取到令牌就通過了。如果沒有取到令牌,請求會進一個Queue中排隊,下一波發令牌的時候優先分配給Queue中請求。Queue滿了之後,請求再進來就會報429。

    • QUICK_RETURN:不會進入Queue排隊,如果沒有取到令牌,直接報429。

  • controlMode: 當時間維度為秒時,指定流控演算法。預設取值TOKEN_BUCKET(令牌桶流控演算法),可以配置為FIX_WINDOW(固定時間視窗流控演算法 )。

3.3. 參數說明

流控外掛程式支援以下位置的參數。

位置名稱

適用範圍

說明

Method

請求

HTTP要求方法 (大寫),如:GET, POST ...

Path

請求

HTTP完整請求路徑,如:/path/to/query

Header

請求

使用Header:{Name}擷取名字為{Name}的HTTP頭的第一個值

Query

請求

使用Query:{Name}擷取QueryString中名字為{Name}的第一個值

Form

請求

使用Form:{Name}擷取請求Form中名字為{Name}的第一個值

Host

請求

使用Host:{Name}擷取匹配到的泛網域名稱模板參數

Parameter

請求

使用Parameter:{Name}擷取使用者API自訂參數中名字為Name的第一個值

System

請求

使用System:{Name}擷取名字為{Name}的系統參數值

Token

請求

當處於jwt,oauth2授權情境時,使用Token:{Name}擷取token中名字為{Name}的值

3.4. 執行規則

API Gateway按照如下的順序執行參數流控:

  • 外掛程式會使用parameters的配置,從請求上下文中擷取參數表。

  • 所有condition執行結果為true或未配置condition的策略都會被執行。

  • 如果命中策略列表中有多條策略的byParameters配置相同,則選擇配置順序靠前的那一條執行,其餘的策略不會生效。

4. 配置範例

4.1. 基礎流控配置範例

基礎流控可支援API流控、不同AppKey、以及不同使用者層級的流控。

---
unit: SECOND           # 預設的流控單位, 支援: SECOND,MINUTE,HOUR,DAY
apiDefault: 50         # API整體流控
defaultRetryAfterBySecond: 60  #預設返回Retry-After標題,它提供建議在下一個請求之前需要等待多長時間
appDefault: 20         # (可選)針對每個APP的流控值, 不大於API整體流控
userDefault: 30        # (可選)針對每個使用者的流控值, 不大於API整體流控
specials:              # (可選)特殊流控, 支援"APP"和"USER"兩種特殊維度
  - type: "APP"        # 針對不同應用(AppKey)進行的流控
    policies:
      - key: 10001     # AppId, AppId的取值請在API Gateway控制台->應用管理->應用詳情處查看
        value: 3       # 特殊流控值, 不大於API整體流控
      - key: 10003
        value: 40
  - type: "USER"       # 針對不同的阿里雲賬戶進行的流控
    policies:
      - key: 102       # 阿里雲帳號ID, 可點擊阿里雲控制台上角查看帳號ID
        value: 10      # 特殊流控值, 不大於API整體流控
      - key: 233
        value: 35

4.2. 按照源IP進行參數限流

在這個例子中,我們配置了的限流策略。

  • 每個源IP允許100次/分鐘的調用

  • 用戶端IP處於58.66.XX.XX/24範圍時,不限制訪問

  • 對用戶端IP為處於63.0.XX.XX,73.0.XX.XX/24範圍時,訪問限制為5次/天

---
scope: API             # 限流的作用範圍,可選API, PLUGIN
parameters:            # 設定限流的參數,我們僅針對用戶端IP進行限流, 用戶端IP從系統變數`CaClientIp`中擷取
  ClientIp: "System:CaClientIp"
rules:
  - name: whitelist    # 白名單策略, 當用戶端IP符合條件時,不執行限流
    condition: "$ClientIp in_cidr '58.66.XX.XX/24'"
    limit: -1          # `-1`表示不進行限流
  - name: banList      # 特殊限制策略, 當用戶端IP符合條件時,按照`ClientIp`參數執行每天5次的限流
    condition: "$ClientIp in_cidr '63.0.XX.XX' or $ClientIp in_cidr '73.0.XX.XX/24'"  
    byParameters: "ClientIp"
    limit: 5
    period: DAY
  - name: 100perIp     # 預設策略,每個IP,100次/分鐘訪問
    byParameters: "ClientIp"
    limit: 100
    period: MINUTE     # 周期,支援:SECOND, MINUTE, HOUR, DAY

4.3 防CC攻擊配置

在這個例子中,我們配置如何防CC攻擊。

  • 每個源IP允許3次/秒鐘的調用

  • 當用戶端源IP超出3次/秒鐘範圍時,訪問將屏蔽10秒鐘

---
scope: API             # 限流的作用範圍,可選API, PLUGIN
defaultLimit: 3000        # 預設流控值
defaultPeriod: SECOND     # 預設流控周期
defaultRetryAfterBySecond: 60  #預設返回Retry-After標題,它提供建議在下一個請求之前需要等待多長時間
parameters:        # 設定限流的參數,我們僅針對用戶端IP進行限流, 用戶端IP從系統變數`CaClientIp`中擷取
  clientIp: "system:CaClientIp"
rules:
  - name: "每個源IP每秒只能訪問3次,一旦觸及閾值,屏蔽10秒鐘"
    byParameters: "clientIp"
    limit: 3
    period: SECOND
    blockingPeriodBySecond: 10     #僅專享執行個體生效

5. 相關錯誤碼

錯誤碼

Http狀態代碼

報錯資訊

描述

T429ID

429

Throttled by INNER DOMAIN Flow Control, ${Domain} is a test domain, only 1000 requests per day

當使用預設次層網域訪問時,限制1000次/天(海外Region及中國香港限制100次/天),請綁定正式網域名稱以解除這個限制

T429IN

429

Throttled by INSTANCE Flow Control

觸發當前執行個體的流控限制

T429GR

429

Throttled by GROUP Flow Control

觸發當前分組的流控限制

T429PA

429

Throttled by API Flow Control

觸發外掛程式上的預設API流控

T429PR

429

Throttled by PLUGIN Flow Control

觸發外掛程式的特殊流控

6. 使用限制

  • 參數定義個數不超過16個。

  • 單個運算式的字元數不超過512個字元。

  • 外掛程式中繼資料的大小限制為50KB

  • 每個外掛程式中rules最大不超過16條。

  • 每個rule中的byParameters最大不超過3個。

  • 當限流參數的分散度太高時,可能釋放掉實際使用資料不高的資料,比如:使用了天層級的源IP流控時,系統儲存了過多的流控記錄時,會釋放掉一部分記錄,在共用執行個體下的參數流控外掛程式允許的不同參數個數為1000,在專享執行個體下的參數流控外掛程式允許的不同參數個數為100000。