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 秒(60÷12)ごとに 1 件のリクエストが許可されます。

<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> と一緒に使用して、特定のクライアントまたはアプリによってリクエストを調整します。

たとえば、SpikeArrest <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 秒(60÷12)ごとに 1 件のリクエストが許可されます。

<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>
子要素 なし

構文

次のいずれかの方法でレートを指定できます。

  • 静的レート。<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 に設定することで、SpikeArrest アルゴリズムを選択できます。

true

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 件目のリクエストも失敗します。

デフォルト値 いいえ
必須かどうか 省略可
ブール値
親要素 <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(内部サーバーエラー)に変更するには、Update organization properties 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 から入手できます。

関連トピック