SpikeArrest 政策

您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件
info

Edge UI 中的尖峰流量抑制圖示

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

請將尖峰流量防護視為一般防範流量遽增的方法,而非將流量限制在特定要求數量的做法。您的 API 和後端可處理一定量的流量,而尖峰流量防範政策可協助您將流量平穩地控制在所需的一般量。

執行階段的尖峰流量防護行為與您輸入的每分鐘或每秒值可能不同。

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

那麼實際情況為何?為避免尖峰流量行為,尖峰流量防範會將設定劃分為較小的間隔,藉此平緩允許的完整要求數量:

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

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

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

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

計算方式:1 項要求 * 訊息處理器數量

根據預設,除非啟用 <UseEffectiveCount>,否則系統不會發布 Spike Arrest。 也就是說,各 MP 的請求次數不會同步。如果有多個訊息處理器,尤其是採用循環配置的訊息處理器,每個都會獨立處理尖峰流量節流。如果只有一個訊息處理器,每分鐘 30 個要求的速率會將流量平滑化為每 2 秒 1 個要求 (60 / 30)。如果使用兩個訊息處理器 (Edge Cloud 的預設值),這個數字會加倍,也就是每 2 秒 2 個要求。因此,請將計算出的每個間隔完整要求數乘以訊息處理器數量,即可得出整體逮捕率。

尖峰流量抑制、尖峰流量限制和配額的差異

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

配額是用來強制執行與開發人員和合作夥伴簽訂的商業合約或服務水準協議,而非用於管理作業流量。使用尖峰流量防護功能,防範 API 流量突然遽增。另請參閱「比較配額、尖峰流量抑制和並行速率限制政策」。

影片

這些影片說明如何使用尖峰流量防範政策,保護 API 免受流量暴增影響:

<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>

以下範例顯示在 Edge UI 中將尖峰流量防範政策新增至流程時的預設設定:

<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>true</UseEffectiveCount>
</SpikeArrest>

此元素在所有政策中皆包含下列屬性:

屬性 預設 必填與否 Description
name 必要

政策的內部名稱。name 屬性的值可以包含英文字母、數字、空格、連字號、底線和半形句號。這個值不得超過 255 個字元。

或者,您也可以使用 <DisplayName> 元素,在管理 UI Proxy 編輯器中,以不同的自然語言名稱來標示政策。

continueOnError false 選填 如果設為「false」,當政策失敗時會傳回錯誤。多數政策預期的行為如下。如果設為「true」,則在政策失敗後,仍會繼續執行流程。
enabled true 選填 設為「true」即可強制執行政策。將政策設為「false」,即可「關閉」政策。即使政策已附加至流程,系統也不會強制執行這項政策。
async   false 已淘汰 這項屬性已淘汰。

範例

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

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

<SpikeArrest name="Spike-Arrest-1">
  <Rate>5ps</Rate>
</SpikeArrest>

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

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

<SpikeArrest async="false" continueOnError="false" enabled="true" name="SpikeArreast">
  <DisplayName>SpikeArreast</DisplayName>
  <Rate>300pm</Rate>
</SpikeArrest>

有效速率為 300pm,也就是每 200 毫秒會在 bucket 中新增一個權杖。儲存區大小一律會設為 messagesPerPeriod 的 10%。因此,如果 messagesPerPeriod 為 300,值區大小就是 30 個權杖。

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

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

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

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

<SpikeArrest name="Spike-Arrest-1">
  <Rate ref="request.header.runtime_rate" />
</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>

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

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

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

預設值 不適用
必填與否 選用
類型 字串
父項元素 <SpikeArrest>
子元素
語法範例 1
<SpikeArrest
  continueOnError="[false|true]"
  enabled="[true|false]"
  name="policy_name"
>
  <Identifier ref="flow_variable"/>
</SpikeArrest>
        

以下範例會根據開發人員 ID 套用尖峰流量防範政策:

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

下表說明 <Identifier> 的屬性:

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

如需這個元素的相關討論,請參閱 Apigee 社群文章:http://community.apigee.com/questions/2807/how-does-the-edge-quota-policy-work-when-no-identi.html

<MessageWeight>

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

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

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

預設值 不適用
必填與否 選用
類型 整數
父項元素 <SpikeArrest>
子元素
語法範例 1
<SpikeArrest
  continueOnError="[false|true]"
  enabled="[true|false]"
  name="policy_name"
>
  <MessageWeight ref="flow_variable"/>
</SpikeArrest>

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

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

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

下表說明 <MessageWeight> 的屬性:

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

<Rate>

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

預設值 不適用
必填與否 必填
類型 整數
父項元素 <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 的值必須是正整數,且不得為零。

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

<SpikeArrest name="Spike-Arrest-1">
  <Rate>5ps</Rate>
</SpikeArrest>

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

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

<SpikeArrest async="false" continueOnError="false" enabled="true" name="SpikeArreast">
  <DisplayName>SpikeArreast</DisplayName>
  <Rate>300pm</Rate>
</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> 元素的本文中設定速率,且用戶端未傳遞值,則 Spike Arrest 政策會擲回錯誤。

選用 不適用

<UseEffectiveCount>

使用自動調度群組時,將尖峰流量抑制計數分配給訊息處理器 (MP)。

語法範例 1
<SpikeArrest
  continueOnError="[false|true]"
  enabled="[true|false]"
  name="policy_name"
>
  <UseEffectiveCount>[false|true]</UseEffectiveCount>
</SpikeArrest>

以下範例會將 <UseEffectiveCount> 設為 true:

<SpikeArrest name='Spike-Arrest-1'>
  <Rate>40ps</Rate>
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

<UseEffectiveCount> 元素為選用項目。如果元素從尖峰流量防護政策中省略,預設值為 false

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

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

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

<UseEffectiveCount> 的效果取決於其值:

  • true:MP 的尖峰速率限制為 <Rate> 除以同一 Pod 中的 MP 目前數量。匯總限制是 <Rate> 的值。動態新增 (或移除) MP 時,個別尖峰速率限制會增加 (或減少),但總計限制維持不變。
  • false:每個 MP 的尖峰速率限制就是其 <Rate> 的值。 總計限制是所有 MP 費率的總和。新增 (或移除) MP 時,個別尖峰率限制不會改變,但總計限制會增加 (或減少)。

SpikeArrest 政策會使用「憑證區塊」演算法,將您指定的速率限制劃分為較小的間隔,藉此緩和流量尖峰。這種做法的缺點是,如果短時間內湧入多個合法要求,可能會遭到拒絕。

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

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

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

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

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

下表顯示 <UseEffectiveCount>對各 MP 有效費率限制的影響:

<UseEffectiveCount> 的值
false false false true true true
監控點數量 8 4 2 8 4 2
<Rate> 的值 10 10 10 40 40 40
每百萬次曝光有效費率 10 10 10 5 10  20
匯總限制 80 40 20 40* 40* 40*
* 與 <Rate> 相同。

在本例中,請注意,當 MP 數量從 4 個減少為 2 個,且 <UseEffectiveCount>false 時,每個 MP 的有效費率維持不變 (為 10)。但當 <UseEffectiveCount>true 時,如果 MP 數量從 4 個減少為 2 個,每個 MP 的有效費率就會從 10 提高至 20。

流程變數

尖峰流量防範政策執行時,系統會填入下列流程變數:

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

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

錯誤參考資料

本節說明系統傳回的錯誤代碼和錯誤訊息,以及錯誤變數。 這項政策觸發錯誤時,由 Edge 設定的。 請務必瞭解這份資訊,以便瞭解您是否要擬定錯誤規則, 處理錯誤詳情請參閱: 注意事項 瞭解政策錯誤處理方式 發生錯誤

執行階段錯誤

執行政策時,可能會發生這些錯誤。

錯誤程式碼 HTTP 狀態 原因 修正
policies.ratelimit.FailedToResolveSpikeArrestRate 500 如果參照包含費率設定的變數,就會發生這個錯誤 無法將 <Rate> 元素中的值解析為尖峰時段中的某個值 政策。此為必要元素,可用來指定 格式為 intpmintps
policies.ratelimit.InvalidMessageWeight 500 如果透過以下其中一種方式為 <MessageWeight> 元素指定值,就會發生這項錯誤。 流量變數無效 (非整數值)。
policies.ratelimit.SpikeArrestViolation 429

超過頻率限制。

部署錯誤

當您部署含有這項政策的 Proxy 時,可能會發生這些錯誤。

錯誤名稱 原因 修正
InvalidAllowedRate 如果在尖峰峰頂攻擊的 <Rate> 元素中指定峰值逮捕率 政策不是整數。如果費率沒有「ps」或「pm」做為後置字串, 那麼 API Proxy 的部署作業就會失敗

錯誤變數

系統會在發生執行階段錯誤時設定這些變數。詳情請參閱重要須知 政策錯誤。

變數 地點 範例
fault.name="fault_name" fault_name 是錯誤的名稱,如 上方的「執行階段錯誤」表格。錯誤名稱是最後一部分 錯誤程式碼 fault.name Matches "SpikeArrestViolation"
ratelimit.policy_name.failed policy_name 是使用者指定錯誤的政策名稱。 ratelimit.SA-SpikeArrestPolicy.failed = true

錯誤回應範例

錯誤回應範例如下:

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

錯誤規則範例

下方為處理 SpikeArrestViolation 錯誤的錯誤規則範例:

<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>

目前,如果超出配額或尖峰流量防護政策設定的速率限制,系統會傳回 429 (要求數超量) 的 HTTP 狀態碼。如要將 HTTP 狀態碼變更為 500 (內部伺服器錯誤),請使用 更新機構資源屬性 API,將 features.isHTTPStatusTooManyRequestEnabled 屬性設為 false

例如:

curl -u email:password -X POST -H "Content-type:application/xml" http://api.enterprise.apigee.com/v1/organizations/myorg -d \
"<Organization type="trial" name="MyOrganization">
    <Properties>
        <Property name="features.isHTTPStatusTooManyRequestEnabled">true</Property>
        . . .
    </Properties>
</Organization>"

結構定義

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

相關主題