SpikeArrest ポリシー

このページの内容は ApigeeApigee ハイブリッドに該当します。

Apigee Edge のドキュメントを表示する。

UI の SpikeArrest アイコン

SpikeArrest ポリシーは、<Rate> 要素を使用してトラフィックの急増から保護します。この要素は、API プロキシで処理され、バックエンドに送信されるリクエスト数を調整します。これにより、パフォーマンスの低下やダウンタイムの発生を防ぎます。

このポリシーは、標準ポリシーであり、任意の環境タイプにデプロイできます。ポリシータイプと各環境タイプで使用可能かどうかは、ポリシータイプをご覧ください。

SpikeArrest と Quota の違い

Quota ポリシーにより、1 時間、1 日、1 週間または 1 か月にクライアント アプリが API に送信できるリクエスト メッセージの数が構成されます。Quota ポリシーは、クライアント アプリに使用制限を適用するために、受信リクエストを集計する分散型カウンタを保持します。

Quota は、運用上のトラフィックを管理するためではなく、デベロッパーやパートナーとの業務契約または SLA を適用するために使用します。API トラフィックの急増を防ぐには、SpikeArrest を使用します。Quota ポリシーと SpikeArrest ポリシーの比較をご覧ください。

動画

以下の動画では、このポリシーのユースケースについて説明しています。

必要な理由

Quota ポリシーとの比較

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

この要素には、すべてのポリシーに共通する次の属性があります。

属性 デフォルト 必須かどうか 説明
name なし 必須

ポリシーの内部名。name 属性の値には、英字、数字、スペース、ハイフン、アンダースコア、ピリオドを使用できます。この値は 255 文字を超えることはできません。

管理 UI プロキシ エディタで <DisplayName> 要素を追加して、ポリシーのラベルに使用する別の自然言語名を指定することもできます。

continueOnError false 省略可 ポリシーが失敗したときにエラーを返す場合は、false に設定します。これは、ほとんどのポリシーで想定される動作です。ポリシーが失敗した後もフローの実行を続行する場合は、true に設定します。関連情報:
enabled true 省略可 ポリシーを適用するには、true に設定します。ポリシーを無効にするには、false に設定します。ポリシーがフローに接続されている場合でも適用されません。
async   false 非推奨 この属性は非推奨となりました。

SpikeArrest ポリシーの使用方法の例をいくつか次に示します。

例 1

次の例では、レートを 1 秒あたり 5 に設定します。

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

このサンプル ポリシーでは、1 秒あたり最大 5 件のリクエストが許可されます。平準化では、200 ミリ秒(1000/5)間隔ごとに最大 1 件のリクエストとして適用されます。

例 2

次の例では、レートが 1 分につき 12 に設定されます。

<SpikeArrest name="Spike-Arrest-1">
  <Rate>12pm</Rate>
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

このサンプル ポリシーでは、5 秒(60÷12)間隔に 1 件のリクエストの割合で、1 分あたり最大 12 件のリクエストが許可されます。5 秒間隔で複数のリクエストがある場合で、リクエスト数が構成されている 1 分あたり 12 回の制限を超えていなければ、そのようなリクエストは許可されます(平滑化なし)。

例 3

次の例では、1 分あたりのリクエスト数が 12 件に制限されます(5 秒ごとに 1 件のリクエストが許可される、つまり 60/12)。

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

また、<MessageWeight> 要素では、特定のアプリやクライアントのメッセージ ウェイトを調整するカスタム値(weight ヘッダー)を使用できます。これにより、<Identifier> 要素で識別されるエンティティのスロットリングをさらに制御できます。

例 4

次の例は、request.header.runtime_rate フロー変数として渡されるリクエストによって設定されたランタイム値を検索するように SpikeArrest に指示します。

<SpikeArrest name="Spike-Arrest-1">
  <Rate ref="request.header.runtime_rate" />
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

フロー変数の値は、intpm または intps の形式にする必要があります。

この例を試すには、次のようなリクエストを行います。

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 レートにカウントされます。

リクエストのスロットリングをよりきめ細かく制御するには、<MessageWeight> 要素と組み合わせて使用します。

<Identifier> 要素を空のままにすると、その API プロキシに対するすべてのリクエストに 1 つのレート制限が適用されます。

デフォルト値 なし
必須 省略可
文字列
親要素 <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> と一緒に使用して、特定のクライアントまたはアプリによってリクエストを調整します。

たとえば、Spike Arrest <Rate>10pm で、ウェイトが 2 のリクエストがアプリで送信される場合、各リクエストは 2 としてカウントされるため、そのクライアントから送信されるメッセージは 1 分あたり 5 件までです。

デフォルト値 なし
必須 省略可
整数
親要素 <SpikeArrest>
子要素 なし

構文

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

例 1

次の例では、1 分あたりのリクエスト数が 12 件に制限されます(5 秒ごとに 1 件のリクエストが許可される、つまり 60/12)。

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

この例では、<MessageWeight> は、特定のクライアントのメッセージ ウェイトを調整するカスタム値(リクエストの weight ヘッダー)を使用しています。これにより、<Identifier> 要素で識別されるエンティティのスロットリングをさらに制御できます。

次の表に、<MessageWeight> 要素の属性を示します。

属性 説明 要否 デフォルト
ref 特定のクライアントのメッセージ ウェイトが含まれるフロー変数を識別します。 これは、HTTP クエリ パラメータ、ヘッダー、メッセージ本文のコンテンツなど、任意のフロー関数にできます。詳細は、フロー変数のリファレンスをご覧ください。また、JavaScript ポリシーまたは AssignMessage ポリシーを使用して、カスタム変数を設定することもできます。 必須 なし

<Rate>

1 分間隔または 1 秒間隔で許可するリクエスト数を指定することによって、トラフィックの急増(またはバースト)を制限するレートを指定します。また、この要素を <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(1 秒あたりのリクエスト数、ミリ秒単位の間隔に平滑化)
  • intpm(1 分あたりのリクエスト数。秒単位の間隔で平準化される)

int の値は、0 以外の正の整数にする必要があります。

例 1

次の例では、レートを 1 秒あたり 5 件のリクエストに設定します。

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

このポリシーでは、200 ミリ秒につき 1 件のリクエスト(1000÷5)が許可されるように、レートが平滑化されます。

例 2

次の例では、レートが 1 分につき 12 件のリクエストに設定されます。

<SpikeArrest name="Spike-Arrest-1">
  <Rate>12pm</Rate>
  <UseEffectiveCount>true</UseEffectiveCount>
</SpikeArrest>

この例のポリシーでは、5 秒ごとに 1 件のリクエスト(60÷12)が許可されるように、レートが平滑化されます。

次の表に、<Rate> 要素の属性を示します。

属性 説明 要否 デフォルト
ref レートを指定するフロー変数を識別します。これは、HTTP クエリ パラメータ、ヘッダー、メッセージ本文の内容などの任意のフロー変数、または KVM などの値にできます。詳細については、フロー変数のリファレンスをご覧ください。

また、JavaScript ポリシーまたは AssignMessage ポリシーを使用してカスタム変数を使用することもできます。

ref とこの要素の本文の両方を定義する場合は、ref の値が適用され、フロー変数がリクエストで設定されている場合にその値が優先されます。リクエストで ref に変数が設定されていない場合は、その逆になります)。

例:

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

この例の場合、クライアントが custom_rate ヘッダーを渡さない場合、すべてのクライアントの API プロキシのレートが 1 分あたり 1 件のリクエストになります。クライアントが custom_rate ヘッダーを渡すと、custom_rate ヘッダーのないリクエストが送信されない限り、プロキシ上のすべてのクライアントのレート上限が 1 秒あたり 10 件になります。

<Identifier> を使用してリクエストをグループ化し、さまざまなタイプのクライアントに対してカスタムレートを適用できます。

ref の値は設定するものの、<Rate> 要素の本文でレートを設定せず、クライアントが値を渡さない場合、SpikeArrest ポリシーでエラーがスローされます。

任意 なし

<UseEffectiveCount>

この要素を使用すると、以下で説明するように、値を true または false に設定することで、個別の Spike Arrest アルゴリズムから選択できます。

はい

true に設定すると、SpikeArrest がリージョンに分散されます。つまり、リクエスト数はリージョン内の Message Processor(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 ポリシーでは「トークン バケット」アルゴリズムが使用されます。このアルゴリズムは、指定したレート制限を短い間隔に分割することで、トラフィックの急増を緩和しますこのアプローチの欠点は、短い間隔で受信された正当なリクエストが拒否される可能性があることです。

たとえば、レートに 30 pm(1 分あたり 30 リクエスト)を入力したとします。テストでは、1 分以内の範囲であれば、30 件のリクエストを 1 秒間で送信してもよいと思われるかもしれません。しかし、これはポリシーにより適用される設定とは異なります。考えてみると、1 秒の間に 30 件のリクエストというのは、環境によっては小規模な急増と見なされることがあります。

  • 1 分あたりのレートは、間隔で許可される完全なリクエスト数に平滑化されます。

    たとえば、30pm は次のように平滑化されます。
    60 秒(1 分)/ 30pm = 2 秒間隔、または 2 秒ごとに 1 回のリクエストが許可されます。2 秒以内の 2 つ目のリクエストは失敗します。また、1 分以内の 31 件目のリクエストも失敗します。

  • 1 秒あたりのレートは、ミリ秒間隔で許可される完全なリクエスト数に平滑化されます。

    たとえば、10ps は次のように平滑化されます。
    1000 ミリ秒(1 秒)/ 10ps = 100 ミリ秒間隔、または 100 ミリ秒ごとに 1 回のリクエスト。100 ミリ秒以内の 2 つ目のリクエストは失敗します。また、1 秒以内の 11 件目のリクエストも失敗します。

デフォルト値 False
必須 省略可
ブール値
親要素 <SpikeArrest>
子要素 なし

次の表に、<UseEffectiveCount> 要素の属性を示します。

属性 説明 デフォルト プレゼンス
ref <UseEffectiveCount> の値が含まれる変数を特定します。これは、HTTP クエリ パラメータ、ヘッダー、メッセージ本文のコンテンツなど、任意のフロー関数にできます。詳細は、フロー変数のリファレンスをご覧ください。また、JavaScript ポリシーまたは AssignMessage ポリシーを使用して、カスタム変数を設定することもできます。 なし 任意

フロー変数

SpikeArrest ポリシーを実行すると、次のフロー変数が設定されます。

変数 権限 説明
ratelimit.policy_name.failed ブール値 読み取り専用 ポリシーが失敗したかどうかを示します(true または false)。

詳細については、フロー変数のリファレンスをご覧ください。

エラー リファレンス

このセクションでは、このポリシーによってエラーがトリガーされたときに返される障害コードとエラー メッセージ、Apigee によって設定される障害変数について説明します。これは、障害に対処する障害ルールを作成するうえで重要な情報です。詳細については、ポリシーエラーについて知っておくべきこと障害の処理をご覧ください。

ランタイム エラー

このエラーは、ポリシーの実行時に発生することがあります。

障害コード HTTP ステータス 原因 修正
policies.ratelimit.FailedToResolveSpikeArrestRate 500 このエラーは、<Rate> 要素内のレート設定を含む変数への参照を、SpikeArrest ポリシー内の値に解決できない場合に発生します。この要素は必須であり、intpm または intps の形式でスパイク阻止レートを指定する場合に使用します。
policies.ratelimit.InvalidMessageWeight 500 このエラーは、フロー変数で <MessageWeight> 要素に指定された値が無効な場合(整数以外の値)場合に発生します。
policies.ratelimit.SpikeArrestViolation 429 レート制限を超過しています。

デプロイエラー

以下のエラーは、このポリシーを含むプロキシをデプロイするときに発生することがあります。

エラー名 原因 修正
InvalidAllowedRate SpikeArrest ポリシーの <Rate> 要素で指定されたスパイク阻止レートが整数でない場合、またはレートに接尾辞として ps または pm がない場合、API プロキシのデプロイは失敗します。

障害変数

ランタイム エラーが発生すると、次の変数が設定されます。詳細については、ポリシーエラーについて知っておくべきことをご覧ください。

変数 説明
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>

Quota ポリシーまたは SpikeArrest ポリシーで設定されたレート制限を超えると、現在の HTTP ステータス コードは 429(リクエストが多すぎます)になります。 HTTP ステータス コードを 500(内部サーバーエラー)に変更するには、組織プロパティ更新 API を使用して features.isHTTPStatusTooManyRequestEnabled プロパティを false に設定します。

例:

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

スキーマ

各ポリシータイプは XML スキーマ(.xsd)によって定義されます。参照用のポリシー スキーマは GitHub から入手できます。

関連トピック