断路器插件(仅专享实例)

断路器是API网关在后端出现性能问题时保护系统的内置机制,本文介绍断路器的后端配置规则。

使用限制

  • 仅专享实例生效。

  • 单个表达式的字符数不超过512个字符。

  • 插件配置大小限制为50KB

1. 断路器概述

断路器在默认配置下,当某个API的后端在30秒钟内出现1000次超时,系统会触发断路器保护,断路器进入打开状态,断路时间为90秒,90秒内所有的请求均快速返回Status=503X-Ca-Error-Code=D503CB错误码,90秒后断路器进入半开状态,允许少量并发请求通过,如果后端恢复正常,则断路器置为关闭状态,请求恢复正常。

当您使用专享实例时,可以通过断路器插件来定制断路器配置,可定制的配置如下:

  • 断路器触发条件,可配置超时模式或者错误码模式。

  • 配置超时窗口。

  • 配置断路器打开状态的超时时间。

  • 配置断路器打开后的降级后端。

2. 配置规则

断路器插件配置仅在API运行在专享实例时生效,如果您使用的是共享实例/Serverless实例,则即使API绑定了断路器插件,也只会使用默认断路器配置。

2.1 按后端超时配置降级策略

可以按照后端超时的方式配置降级策略。若API定义的后端超时时间为10s,请求后端10s没有应答就会计为后端超时

timeoutThreshold: 15         # 超时的阈值
windowInSeconds: 30          # 超时时间窗口
openTimeoutSeconds: 15       # 断路器开的时间
downgradeBackend:            # 降级后的后端配置
  type: mock
  statusCode: 418

配置字段说明:

  • timeoutThreshold: 超时阈值,上限为5000,注意如果配置过低,可能导致几次超时就触发断路器。

  • windowInSeconds: 判断时间窗口,合法值为10~90秒。

  • openTimeoutSeconds: 断路器开的持续时间,合法值为15~300秒。

  • downgradeBackend: (可选)当断路器出现降级时,降级后端。

2.2 按后端响应时间配置降级策略

可以按照后端的响应时间配置降级策略。后端响应时间为网关给后端发送请求到收到后端应答的耗时。

errorThreshold: 10          # 错误出现的阈值
windowInSeconds: 60         # 判断错误次数的时间窗口
openTimeoutSeconds: 120      # 断路器打开的持续时间
errorCondition: "$LatencyMilliSeconds > 500"     # 错误条件:后端响应时间大于500ms
downgradeBackend:               # 降级后的后端配置
  type: mock
  statusCode: 403

配置字段说明:

  • errorThreshold: 错误出现的阈值。

  • windowsInSeconds: 判断时间窗口,合法值为10~90秒。

  • openTimeoutSeconds: 断路器开的持续时间,合法值为15~300秒。

  • errorCondition: 错误条件表达式,$LatencyMilliSeconds$LatencySeconds两个变量可以用于对后端耗时进行判断。 $LatencyMilliSeconds的单位为毫秒(ms),$LatencySeconds的单位为秒(s)。

  • downgradeBackend: (可选) 当断路器出现降级时,降级后端。

2.3 按后端报错配置降级策略

可以按照后端错误码的方式配置降级策略。

errorCondition: "$StatusCode == 503"  # 错误条件
errorThreshold: 1000                  # 错误阈值
windowInSeconds: 30                   # 超时窗口时间
openTimeoutSeconds: 15                # 断路器开的时间
downgradeBackend:                     # 降级后端
  type: "HTTP"
  address: "http://api.foo.com"
  path: "/system-busy.json"
  method: GET
  • errorCondition: 错误条件表达式,$StatusCode$LatencySeconds两个变量可以用于对后端的应答码以及耗时(秒)进行判断。

    • 如:$StatusCode = 503 or $StatusCode = 504,当后端应答为503或504。

    • 如:$LatencySeconds > 30,当超时大于30秒时。

  • errorThreshold: 错误出现的阈值。

  • windowsInSeconds: 判断时间窗口,合法值为10~90秒。

  • openTimeoutSeconds: 断路器开的持续时间,合法值为15~300秒。

  • downgradeBackend: (可选) 当断路器出现降级时,降级后端。

2.4 精准状态控制

为了保证高可用性和高性能,API网关采用集群模式将应用服务部署在多个节点上,属于分布式架构。默认情况下,不同的服务节点会独立计算并保存断路器的状态,因此从全局角度来看,断路器可能出现状态不准确的情况。如果您对断路器的精度有较高的要求,那么可以在插件配置信息中添加useGlobalState字段,示例如下:

---
timeoutThreshold: 15 # 超时出现的阈值
windowInSeconds: 30 # 判断超时的时间窗口
openTimeoutSeconds: 15 # 断路器打开的超时时间
useGlobalState: true # 开启精准状态控制
downgradeBackend: # 降级后的后端配置
 type: mock
 statusCode: 302
 body: |
 <result>
 <errorCode>I's a teapot</errorCode>
 </result>

useGlobalState默认为false,开启后断路器可实现精准状态控制,此时网关服务会有一定的性能损耗,但仍然能够满足当前实例所承诺的QPS和SLA指标。

2.5 按百分比来配置降级策略

目前支持根据以下四个条件判断,无论哪个条件触发,降级策略都会生效,没有优先级。

  • errorThreshold:错误阈值,需配合错误条件使用。

  • timeoutThreshold:后端超时的阈值。

  • errorThresholdByPercent:错误阈值的百分比,是根据上一个时间窗口的错误百分比来判断的。

  • timeoutThresholdByPercent:后端超时的百分比,是根据上一个时间窗口的后端超时百分比来判断的。

示例如下:

---
windowInSeconds: 3  # 判断时间窗口,合法值为10~90秒
openTimeoutSeconds: 3
errorThreshold: 90  # 错误阈值
timeoutThreshold: 90   # 后端超时阈值
errorThresholdByPercent: 20    # 用于控制错误阈值的百分比
timeoutThresholdByPercent: 20   # 用于控制后端超时请求的百分比
errorCondition: "$StatusCode = 500"   # 错误条件
downgradeBackend:
  type: mock
  statusCode: 418
  body: |
    <result>
      <errorCode>I's a teapot</errorCode>
    </result>
重要
  • 当用百分比来配置降级策略时,上一个时间窗口的请求次数需要大于100次,小于100次此规则不生效。

  • 本示例中errorThreshold: 90 timeoutThreshold: 90 指的是,如果本时间窗口错误请求数/后端超时请求数量超过90次,则触发断路器策略;

  • 本示例中errorThresholdByPercent: 20 timeoutThresholdByPercent: 20指的是,如果上一个时间窗口总请求数为100次并且错误请求数/后端超时请求数超过20次,则本时间窗口触发断路器策略。

  • 2023年6月版本后支持按照超时请求数所占百分比来配置降级策略。

2.6 断路器增加流控策略

一旦触发断路器条件,会在API上增加一个临时流控,在半开状态和全开状态所有流量全部走这个流控:

---
windowInSeconds: 1             # 判断超时次数的时间窗口
openTimeoutSeconds: 15          # 断路器打开的超时时间
errorThreshold: 3
errorCondition: "$LatencyMilliSeconds > 1"
downgradeTrafficLimit:               # 降级后的后端配置
  limit: 2
  period: MINUTE

3. 降级后端配置

当断路器打开时,可以通过配置downgradeBackend来设定断路器打开后的返回,返回的结构与API网关的Swagger结构一致,请参考文档通过导入Swagger创建API,目前支持的后端类型及配置样例如下:

  • HTTP后端

---
backend:
  type: HTTP
  address: "http://10.10.100.2:8000"
  path: "/users/{userId}"
  method: GET
  timeout: 7000        
  • HTTP后端(VPC)

---
backend:
  type: HTTP-VPC
  vpcAccessName: vpcAccess1
  path: "/users/{userId}"
  method: GET
  timeout: 10000        
  • 函数计算

---
backend:
  type: FC
  fcRegion: cn-shanghai
  serviceName: fcService
  functionName: fcFunction
  arn: "acs:ram::111111111:role/aliyunapigatewayaccessingfcrole"        
  • MOCK

---
backend:
  type: MOCK
  mockResult: "mock result sample"
  mockStatusCode: 200
  mockHeaders:
    - name: Content-Type
      value: text-plain
    - name: Content-Language
      value: zhCN

4. 相关错误码

错误代码

HTTP状态码

Message

描述

D503BB

503

Backend circuit breaker busy

API被断路器阻止。

D503CB

503

Backend circuit breaker open, ${Reason}

API处于熔断/断路器开状态,请检查后端性能后稍后再试。