SpikeArrest 政策

本頁內容適用於 ApigeeApigee Hybrid

查看 Apigee Edge 說明文件。

UI 中的 SpikeArrest 圖示

SpikeArrest 政策會使用 <Rate> 元素防範流量暴增。這個元素會限制 API Proxy 處理並傳送到後端的要求數,防範效能延遲和停機。

這項政策屬於標準政策,可部署至任何環境類型。如要瞭解各環境類型適用的政策類型和可用性,請參閱「政策類型」。

SpikeArrest 和配額的差異

配額政策會設定用戶端應用程式在 1 小時、1 天、1 週或 1 個月內,可向 API 提交的要求訊息數量。配額政策會維護分散式計數器,計算傳入的要求,藉此對用戶端應用程式強制執行用量限制。

配額是用來強制執行與開發人員和合作夥伴簽訂的商業合約或服務水準協議,而不是用於管理作業流量。使用 SpikeArrest 防範 API 流量突然暴增。另請參閱比較配額和 SpikeArrest 政策

影片

這些影片會討論這項政策的適用情況:

重要性

比較配額政策

<SpikeArrest> 元素

定義 SpikeArrest 政策。

預設值 請參閱下方的「預設政策」分頁
必填與否 選用
類型 複雜物件
父項元素 不適用
子元素 <Identifier>
<MessageWeight>
<Rate> (必要)
<UseEffectiveCount>

語法

<SpikeArrest> 元素使用下列語法:

<SpikeArrest
  continueOnError="[false|true]"
  enabled="[true|false]"
  name="policy_name"
>
  <DisplayName>display_name</DisplayName>
  <Properties/>
  <Identifier ref="flow_variable"/>
  <MessageWeight ref="flow_variable"/>
  <Rate ref="flow_variable">rate[pm|ps]</Rate>
  <UseEffectiveCount>[false|true]</UseEffectiveCount>
</SpikeArrest>

預設政策

以下範例顯示在 UI 中將 SpikeArrest 政策新增至流程時的預設設定:

<SpikeArrest async="false" continueOnError="false" enabled="true" name="Spike-Arrest-1">
  <DisplayName>Spike Arrest-1</DisplayName>
  <Properties/>
  <Identifier ref="request.header.some-header-name"/>
  <MessageWeight ref="request.header.weight"/>
  <Rate>30ps</Rate>
  <UseEffectiveCount>false</UseEffectiveCount>
</SpikeArrest>

This element has the following attributes that are common to all policies:

Attribute Default Required? Description
name N/A Required

The internal name of the policy. The value of the name attribute can contain letters, numbers, spaces, hyphens, underscores, and periods. This value cannot exceed 255 characters.

Optionally, use the <DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

continueOnError false Optional Set to false to return an error when a policy fails. This is expected behavior for most policies. Set to true to have flow execution continue even after a policy fails. See also:
enabled true Optional Set to true to enforce the policy. Set to false to turn off the policy. The policy will not be enforced even if it remains attached to a flow.
async   false Deprecated This attribute is deprecated.

範例

以下範例說明 SpikeArrest 政策的幾種用法:

範例 1

以下範例將速率設為每秒五個:

<SpikeArrest name="SA-Static-5ps">
  <Rate>5ps</Rate>
  <UseEffectiveCount>false</UseEffectiveCount>
</SpikeArrest>

這項範例政策允許每秒最多 5 個要求。透過平滑化,系統會強制執行每 200 毫秒 (1000/5) 間隔最多一個要求的限制。

範例 2

以下範例將速率設為每分鐘 12 次:

<SpikeArrest name="SA-Static-12pm">
  <Rate>12pm</Rate>
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

這項範例政策允許每分鐘最多 12 個要求,也就是每隔 5 (60/12) 傳送一個要求。如果 5 間隔內有多個要求,只要要求數量低於設定的每分鐘 12 個要求速率限制,系統就會允許這些要求 (不進行平滑處理)。

範例 3

下列範例將要求限制為每分鐘 12 個 (每五秒允許一個要求,或 60/12):

<SpikeArrest name="SA-With-Dynamic-Weight-1">
  <Rate>12pm</Rate>
  <Identifier ref="client_id" />
  <MessageWeight ref="request_specific_weight" />
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

此外,<MessageWeight> 元素接受自訂值 (weight 標頭),可調整特定應用程式或用戶端的訊息權重。這樣就能進一步控管以 <Identifier> 元素識別的實體節流。

範例 4

以下範例會指示 SpikeArrest 尋找透過要求設定的執行階段值,並以 request.header.runtime_rate 流程變數的形式傳遞:

<SpikeArrest name="SA-From-Inbound-Header-1">
  <Rate ref="request.header.runtime_rate" />
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

流程變數的值必須為 intpmintps 形式。

如要試用這個範例,請執行類似下列內容的要求:

curl http://myorg-myenv.apigee.net/price -H 'runtime_rate:30ps'

子元素參照

本節說明 <SpikeArrest> 的子元素。

<DisplayName>

除了 name 屬性之外,您也可以在管理 UI 代理程式編輯器中使用其他更自然的名稱標記政策。

<DisplayName> 元素適用於所有政策。

預設值 不適用
是否必要? (非必要) 如果省略 <DisplayName>,系統會使用政策的 name 屬性值。
類型 字串
上層元素 <PolicyElement>
子元素

<DisplayName> 元素使用以下語法:

語法

<PolicyElement>
  <DisplayName>POLICY_DISPLAY_NAME</DisplayName>
  ...
</PolicyElement>

範例

<PolicyElement>
  <DisplayName>My Validation Policy</DisplayName>
</PolicyElement>

<DisplayName> 元素沒有屬性或子項元素。

<Identifier>

可讓您選擇如何將要求分組,以便根據用戶端套用 SpikeArrest 政策。舉例來說,您可以依開發人員 ID 將要求分組,這樣一來,每個開發人員的要求都會計入各自的 SpikeArrest 速率,而非所有對 Proxy 的要求。

搭配 <MessageWeight> 元素使用,可更精細地控管要求節流。

如果將 <Identifier> 元素留空,系統會對該 API 代理的所有要求強制執行一項速率限制。

預設值 不適用
必填與否 選用
類型 字串
父項元素 <SpikeArrest>
子元素

語法

<SpikeArrest
  continueOnError="[false|true]"
  enabled="[true|false]"
  name="policy_name"
>
  <Identifier ref="flow_variable"/>
</SpikeArrest>
        

範例 1

以下範例會根據開發人員 ID 套用 SpikeArrest 政策:

<SpikeArrest name="Spike-Arrest-1">
  <Identifier ref="developer.id"/>
  <Rate>42pm</Rate/>
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

下表說明 <Identifier> 的屬性:

屬性 說明 預設 存在必要性
ref 識別 SpikeArrest 用來將傳入要求分組的變數。 您可以使用任何流程變數來指出不重複的用戶端,例如 VerifyAPIKey 政策提供的變數。您也可以使用 JavaScript 政策AssignMessage 政策設定自訂變數。 不適用 必填

這篇 Apigee 社群貼文也討論了這個元素。

<MessageWeight>

指定為每則訊息定義的權重。訊息權重會影響單一要求對 SpikeArrest 速率計算的影響。訊息權重可以是任何流程變數,例如 HTTP 標頭、查詢參數、表單參數或訊息主體內容。您也可以使用 JavaScript 政策AssignMessage 政策,自訂變數。

<Identifier> 搭配使用,可進一步依特定用戶端或應用程式限制要求。

舉例來說,如果 SpikeArrest <Rate>10pm,且應用程式提交的要求權重為 2,則該用戶端每分鐘只能傳送五則訊息,因為每個要求都算 2。

預設值 不適用
必填與否 選用
類型 整數
父項元素 <SpikeArrest>
子元素

語法

<SpikeArrest
  continueOnError="[false|true]"
  enabled="[true|false]"
  name="policy_name"
>
  <MessageWeight ref="flow_variable"/>
</SpikeArrest>

範例 1

下列範例將要求限制為每分鐘 12 個 (每五秒允許一個要求,或 60/12):

<SpikeArrest name="SA-With-Dynamic-Weight-1">
  <Rate>12pm</Rate>
  <Identifier ref="client_id" />
  <MessageWeight ref="request_specific_weight" />
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

在本範例中,<MessageWeight> 接受自訂值 (要求中的 weight 標頭),可調整特定用戶端的訊息權重。這樣就能進一步控管以 <Identifier> 元素識別的實體節流。

下表說明 <MessageWeight> 的屬性:

屬性 說明 存在必要性 預設
ref 用於識別包含特定用戶端訊息權重的流程變數。 可以是任何流程變數,例如 HTTP 查詢參數、標頭或訊息主體內容。詳情請參閱流程變數參考資料。您也可以使用 JavaScript 政策AssignMessage 政策設定自訂變數。 必填 不適用

<Rate>

設定每分鐘或每秒間隔允許的要求數,指定限制流量尖峰 (或爆量) 的速率。您也可以搭配使用這個元素與 <Identifier><MessageWeight>,接受來自用戶端的值,在執行階段順暢地節流流量。使用 <UseEffectiveCount> 元素設定政策使用的速率限制演算法。

如要瞭解可指定的速率限制上限,請參閱「限制」頁面的「SpikeArrest」一節

預設值 不適用
必填與否 必填
類型 整數
父項元素 <SpikeArrest>
子元素

語法

您可以透過下列任一方式指定費率:

  • 您指定為 <Rate> 元素主體的靜態費率
  • 變數值,可由用戶端傳遞;使用 ref 屬性識別流程變數的名稱
<SpikeArrest
  continueOnError="[false|true]"
  enabled="[true|false]"
  name="policy_name"
>
  <Rate ref="flow_variable">rate[pm|ps]</Rate>
</SpikeArrest>

有效費率值 (定義為變數值或元素主體) 必須符合下列格式:

  • intps (每秒要求數,平滑處理為毫秒間隔)
  • intpm (每分鐘要求數,以秒為間隔平滑化)

int 的值必須是正整數,且不得為零。

範例 1

以下範例將速率設為每秒五項要求:

<SpikeArrest name="SA-Static-5ps">
  <Rate>5ps</Rate>
  <UseEffectiveCount>false</UseEffectiveCount>
</SpikeArrest>

這項政策會將速率調整為每 200 毫秒允許一個要求 (1000/5)。

範例 2

以下範例將速率設為每分鐘 12 項要求:

<SpikeArrest name="SA-Static-12pm">
  <Rate>12pm</Rate>
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

這項範例政策會將速率調降為每五允許一個要求 (60/12)。

下表說明 <Rate> 的屬性:

屬性 說明 存在必要性 預設
ref 識別指定費率的流程變數。這可以是任何流程變數,例如 HTTP 查詢參數、標頭或訊息主體內容,也可以是 KVM 等值。詳情請參閱流程變數參考資料

您也可以使用 JavaScript 政策AssignMessage 政策,自訂變數。

如果您同時定義 ref 這個元素的主體,當要求中設定流程變數時,系統會套用 ref 的值,並優先採用該值。(如果要求中ref設定變數,則反之亦然)。

例如:

<Rate ref="request.header.custom_rate">1pm</Rate>

在本例中,如果用戶端傳遞 custom_rate 標頭,則所有用戶端的 API Proxy 速率為每分鐘 1 個要求。如果用戶端傳遞 custom_rate 標頭,則 Proxy 上的所有用戶端都會受到每秒 10 項要求的速率限制,直到傳送不含 custom_rate 標頭的要求為止。

您可以透過 <Identifier> 將要求分組,為不同類型的客戶強制執行自訂費率。

如果您為 ref 指定值,但未在 <Rate> 元素的本文中設定速率,且用戶端未傳遞值,SpikeArrest 政策就會擲回錯誤。

選用 不適用

<UseEffectiveCount>

您可以將值設為 truefalse,在不同的尖峰抑制演算法之間選擇,如下所述:

如果設為 true,SpikeArrest 會分散在一個區域中。也就是說,區域中訊息處理器 (MP) 的要求計數會同步處理。此外,系統還會採用「滑動視窗」頻率限制演算法。這項演算法可提供一致的速率限制行為,且不會「平滑化」可傳送至後端的傳入要求數量。如果在短時間間隔內傳送大量要求,只要不超過 <Rate> 元素中設定的速率限制,系統就會允許這些要求。例如:

<SpikeArrest name="Spike-Arrest-1">
  <Rate>12pm</Rate>
  <Identifier ref="client_id" />
  <MessageWeight ref="request.header.weight" />
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

false (預設)

如果設為 false (預設值),SpikeArrest 政策會使用「權杖 bucket」演算法,將您指定的速率限制劃分為較小的間隔,藉此緩和流量遽增情形。這種做法的缺點是,如果短時間內湧入多項合法要求,可能會遭到拒絕。

舉例來說,假設您輸入的速率為 30pm (每分鐘 30 個要求)。在測試時,您可能會認為只要要求是在一分鐘內送達,您就能在一秒內傳送 30 個要求。但政策並非以這種方式強制執行設定。如果考慮到 1 秒內有 30 個要求,在某些環境中,這可能算是小型尖峰。

  • 系統會將每分鐘的速率平滑化,並以為間隔,允許完整的要求。

    舉例來說,30pm 的平滑處理方式如下:
    60 秒 (1 分鐘) / 30pm = 2 秒間隔,也就是每 2 秒可發出 1 個要求。如果間隔不到 2 秒就提出第二個要求,就會失敗。此外,如果在一分鐘內提出第 31 項要求,系統會拒絕該要求。

  • 每秒速率會平滑化,以毫秒為間隔,計算出允許的完整要求數。

    舉例來說,10ps 的平滑處理方式如下:
    1000 毫秒 (1 秒) / 10ps = 100 毫秒間隔,或每 100 毫秒允許 1 個要求。如果 100 毫秒內發出第二個要求,就會失敗。此外,如果在一秒內提出第 11 個要求,就會失敗。

預設值
必填與否 選用
類型 布林值
父項元素 <SpikeArrest>
子元素

下表說明 <UseEffectiveCount> 元素的屬性:

屬性 說明 預設 存在必要性
ref 識別含有 <UseEffectiveCount> 值的變數。可以是任何流程變數,例如 HTTP 查詢參數、標頭或訊息主體內容。詳情請參閱流程變數參考資料。您也可以使用 JavaScript 政策AssignMessage 政策設定自訂變數。 不適用 選用

流程變數

執行 SpikeArrest 政策時,系統會填入下列流程變數:

變數 類型 權限 說明
ratelimit.policy_name.failed 布林值 唯讀 指出政策是否失敗 (truefalse)。

詳情請參閱流程變數參考資料

錯誤參考資料

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.

Runtime errors

These errors can occur when the policy executes.

Fault code HTTP status Cause Fix
policies.ratelimit.FailedToResolveSpikeArrestRate 500 This error occurs if the reference to the variable containing the rate setting within the <Rate> element cannot be resolved to a value within the SpikeArrest policy. This element is mandatory and used to specify the spike arrest rate in the form of intpm or intps.
policies.ratelimit.InvalidMessageWeight 500 This error occurs if the value specified for the <MessageWeight> element through a flow variable is invalid (a non-integer value).
policies.ratelimit.SpikeArrestViolation 429 The rate limit is exceeded.

Deployment errors

These errors can occur when you deploy a proxy containing this policy.

Error name Cause Fix
InvalidAllowedRate If the spike arrest rate specified in the <Rate> element of the SpikeArrest policy is not an integer or if the rate does not have ps or pm as a suffix, then the deployment of the API proxy fails.

Fault variables

These variables are set when a runtime error occurs. For more information, see What you need to know about policy errors.

Variables Where Example
fault.name="fault_name" fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. fault.name Matches "SpikeArrestViolation"
ratelimit.policy_name.failed policy_name is the user-specified name of the policy that threw the fault. ratelimit.SA-SpikeArrestPolicy.failed = true

Example error response

Shown below is an example error response:

{  
   "fault":{  
      "detail":{  
         "errorcode":"policies.ratelimit.SpikeArrestViolation"
      },
      "faultstring":"Spike arrest violation. Allowed rate : 10ps"
   }
}

Example fault rule

Shown below is an example fault rule to handle a SpikeArrestViolation fault:

<FaultRules>
    <FaultRule name="Spike Arrest Errors">
        <Step>
            <Name>JavaScript-1</Name>
            <Condition>(fault.name Matches "SpikeArrestViolation") </Condition>
        </Step>
        <Condition>ratelimit.Spike-Arrest-1.failed=true</Condition>
    </FaultRule>
</FaultRules>

目前,如果超出配額或 SpikeArrest 政策設定的速率限制,系統會傳回 HTTP 狀態碼 429 (要求數超量)。

結構定義

每個政策類型都由 XML 架構 (.xsd) 定義。如需參考,請前往 GitHub 查看政策架構

相關主題