SpikeArrest 政策

本页面适用于 ApigeeApigee Hybrid

查看 Apigee Edge 文档。

界面上的 SpikeArrest 图标

SpikeArrest 政策通过 <Rate> 元素防止流量激增。此元素限制 API 代理处理并发送到后端的请求数,从而避免性能滞后和停机。

此政策为标准政策,可部署到任何环境类型。如需了解政策类型以及在每种环境类型中的可用性,请参阅政策类型

SpikeArrest 和配额之间的差异

配额政策配置允许客户端应用在一小时、一日、一周或一个月内提交给 API 的请求消息的数量。配额政策通过维护分布式计数器计算传入请求,从而对客户端应用强制执行使用限制。

使用配额可以强制执行与开发者和合作伙伴签署的业务合同或服务等级协议 (SLA),而不是运营流量管理。使用 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>

默认政策

以下示例显示您向界面中的流添加 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

以下示例将速率设置为每秒 5 个:

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

以下示例政策允许每秒最多 5 个请求。经过平滑处理后,每 200 毫秒 (1000/5) 间隔最多可发出一个请求。

示例 2

以下示例将费率设置为每分钟 12 个:

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

此示例政策允许每分钟最多 12 个请求,速率为每 5 秒 (60/12) 间隔 1 个请求。如果 5 时间段内有多个请求,则只要请求数量小于配置的每分钟 12 个请求的速率限制,系统便会允许发出这些请求(未经过平滑处理)。

示例 3

以下示例将请求限制为每分钟 12 个(每 5 秒 (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

以下示例指示 SpikeArrest 查找通过作为 request.header.runtime_rate 流变量传递的请求所设置的运行时值:

<SpikeArrest name="Spike-Arrest-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>

Use in addition to the name attribute to label the policy in the management UI proxy editor with a different, more natural-sounding name.

The <DisplayName> element is common to all policies.

Default Value N/A
Required? Optional. If you omit <DisplayName>, the value of the policy's name attribute is used.
Type String
Parent Element <PolicyElement>
Child Elements None

The <DisplayName> element uses the following syntax:

Syntax

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

Example

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

The <DisplayName> element has no attributes or child elements.

<Identifier>

您可以选择对请求进行分组的方式,从而根据客户端应用 SpikeArrest 政策。例如,您可以按开发者 ID 对请求进行分组,这种情况下,每个开发者的请求将计入他们自己的 SpikeArrest 速率,而不是向代理进行的所有请求。

您可以将其与 <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 的请求,则该客户端每分钟只能发送 5 条消息,因为每个请求将计为 2。

默认值 不适用
是否必需? 可选
类型 整数
父元素 <SpikeArrest>
子元素

语法

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

示例 1

以下示例将请求限制为每分钟 12 个(每 5 秒 (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>

通过设置每分钟或每秒允许的请求数来指定采用哪个速率限制流量高峰(或爆发)。您还可以将该元素与 <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

以下示例将速率设置为每秒 5 个请求:

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

此政策将速率平滑处理为每 200 毫秒 (1000/5) 允许一个请求。

示例 2

以下示例将费率设置为每分钟 12 个请求:

<SpikeArrest name="Spike-Arrest-1">
  <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 代理的速率是所有客户端每分钟 1 个请求。如果客户端传递 custom_rate 标头,则速率限制是代理上所有客户端每秒 10 个请求,直到发送不带 custom_rate 标头的请求。

您可以使用 <Identifier> 对请求类型进行分组,以便对不同类型的客户端强制执行自定义速率。

如果您为 ref 指定了值,但没有在 <Rate> 元素的正文中设置速率,而客户端没有传递值,则 SpikeArrest 政策会抛出一个错误。

可选 不适用

<UseEffectiveCount>

借助该元素,您可以将值设为 truefalse,从而在不同的高峰控制算法之间进行选择,如下所述:

true

如果设置为 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 政策将使用“令牌桶”算法,通过将指定的速率限制划分为更小的时间间隔来平滑流量高峰。这种方法的缺点是,短时间内传入的多个合法请求可能会被拒绝。

举例来说,假设您输入了一个 30pm 的速率(每分钟 30 个请求)。在测试时,您可能认为您可以在 1 秒内发送 30 个请求,只要在 1 分钟内即可。但该政策并非这样执行这种设置的。如果您思考一下就会明白,某些环境中 1 秒钟内 30 个请求会被视为是一个小型高峰。

  • 每分钟速率可以以为时间间隔,平滑发送允许的全部请求。

    例如,30pm 会按以下所示实现平滑发送:
    60 秒(1 分钟)/30pm = 间隔时间为 2 秒,或每 2 秒允许 1 个请求。2 秒内发出的第二个请求将会失败。同时,一分钟内发出的第 31 个请求将会失败。

  • 每秒速率会以毫秒为时间间隔,平滑发送允许的全部请求。

    例如,10ps 会按以下所示实现平滑发送:
    1000 毫秒(1 秒钟)/10ps = 间隔时间为 100 毫秒,或每 100 毫秒允许 1 个请求。100 毫秒内发出的第二个请求将会失败。同时,一秒钟内发出的第 11 个请求将会失败。

默认值 False
是否必需? 可选
类型 布尔值
父元素 <SpikeArrest>
子元素

下表说明了 <UseEffectiveCount> 元素的属性:

属性 说明 默认 状态
ref 标识包含 <UseEffectiveCount> 值的变量。这可以是任何流变量,例如 HTTP 查询参数、标头或消息正文内容。如需了解详情,请参阅流变量参考文档。此外,您还可以使用 JavaScript 政策AssignMessage 政策设置自定义变量。 不适用 可选

流变量

当执行 SpikeArrest 政策时,系统会填充以下流变量:

变量 类型 权限 说明
ratelimit.policy_name.failed 布尔值 只读 指示政策是否失败(truefalse)。

如需了解详情,请参阅流变量参考文档

错误参考信息

本部分介绍当此政策触发错误时返回的故障代码和错误消息,以及由 Apigee 设置的故障变量。在开发故障规则以处理故障时,请务必了解此信息。如需了解详情,请参阅您需要了解的有关政策错误的信息处理故障

运行时错误

政策执行时可能会发生这些错误。

故障代码 HTTP 状态 原因 修复
policies.ratelimit.FailedToResolveSpikeArrestRate 500 如果对包含在 <Rate> 元素中设置的速率的变量的引用无法解析为 SpikeArrest 政策中的值,则会出现此错误。此元素是必需的,以 intpmintps 的形式指定 Spike Arrest 速率。
policies.ratelimit.InvalidMessageWeight 500 如果通过流变量为 <MessageWeight> 元素指定的值无效(非整数值),就会出现此错误。
policies.ratelimit.SpikeArrestViolation 429 超出速率限制。

部署错误

在您部署包含此政策的代理时,可能会发生这些错误。

错误名称 原因 修复
InvalidAllowedRate 如果在 SpikeArrest 政策的 <Rate> 元素中指定的 Sprike Arrest 速率不是整数,或者该速率不是 pspm,则 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>

超出配额或 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 提供了政策架构作为参考。

相关主题