如何处理瞬时故障?

在服务网格中使用 Envoy 的一个最大优势就是它让服务从实现复杂的弹性功能解脱出来,如熔断、异常检测以及重试,这些让服务应对实际情况时更具弹性,常见的诸如滚动升级、动态基础设施变更以及网络故障。Envoy 中实现的上述功能不仅仅提高了服务可用性和韧性,而且在行为和观测性方面带来了一致性。

这部分将从一个较高层次来解释 Envoy 支持的配置以及如何一起使用这些功能来处理这些场景。

熔断

熔断 是分布式系统非常重要的一环。熔断可以让应用程序配置故障阈值,以确保最大限度的安全,允许组件快速失败然后尽可能快的恢复正常。使用正确的熔断阈值有助于节省那些浪费在请求等待(超时)或者非必要的请求重试中的资源。对于在 Envoy 中实现的熔断来讲 ,一个主要的优势是熔断限制可以被应用在网络层。 .. _common_configuration_transient_failures_retries:

重试

自动的 请求重试 是另外一种保证服务弹性的方法。请求重试通常应用于防范瞬时故障。Envoy 支持非常丰富的可配置参数来指定请求重试的类型、请求重试的次数以及请求重试的超时时间等。

gRPC 服务中的重试

对于 gRPC 服务,Envoy 会在响应中查看 gRPC 状态,然后基于在 x-envoy-retry-grpc-on 中配置的状态来尝试重试。

对于自动重试来讲,gRPC 中的下述应用程序状态码被认为是安全的。

  • CANCELLED - 在服务中如果有一个可重试的错误,则返回此码。

  • RESOURCE_EXHAUSTED - 如果服务所依赖的某些资源在该实例中耗尽,则重试至另外一个实例来获取帮助,在这种情况下返回此码。请注意对于共享资源的耗尽,返回此码将不会有任何帮助。应使用 速率限制 来处理这种情况。

HTTP 状态码 502 (Bad Gateway)503 (Service Unavailable)504 (Gateway Timeout) 都和 gRPC 状态码 UNAVAILABLE 做了映射。针对自动重试来讲,这可被视为是安全的。

在配置重试时,请求的幂等性需要被重点考虑。

Envoy 同样支持对重启策略的扩展。重试插件 允许为应用程序来定制 Envoy 重试实现。

异常检测

异常检测 是一种在上游集群中动态检测行为异常的主机的一种方法。通过探测这些主机并将它们从健康的负载均衡集中临时驱逐出去,Envoy 能够提高集群的成功率。Envoy 支持基于连续的 5xx、连续的网关失败和成功率来配置异常检测。

Envoy 也允许你配置驱逐周期。

配置

下述配置有助于优化:

  • 常见场景下的最大请求成功率(比如,滚动升级)

  • 速度

  • 避免级联故障

熔断

{
   "thresholds": [
     {
       "max_retries": 10,
     }
  ]
}

在这个特定用例中,需要配置上游集群的重试预算来开启并控制并发重试次数。如果配置的值过低,部分请求将不会被重试,可以通过 upstream_rq_retry_overflow 来进行一个衡量。如果值配置的过高,服务可能会被重试请求淹没。

异常检测

{
   "consecutive_5xx": 5,
   "base_ejection_time": "30s",
   "max_ejection_percent": 50,
   "consecutive_gateway_failure": 5,
}

如果有 5 个连续的 5xx 或者 网关失败,上述设置就会开启异常检测,而且会将驱逐的主机数量限制为上游集群大小的 50%。此配置对删除的主机数设置了安全限制。请注意,一旦一个主机被驱逐,它将会在一个驱逐周期(通常等于 base_ejection_time 与主机被驱逐次数的乘积)过后重新回到主机池。

请求重试

{
   "retry_on": "cancelled,connect-failure,gateway-error,refused-stream,reset,resource-exhausted,unavailable",
   "num_retries": 1,
   "retry_host_predicate": [
   {
      "name": "envoy.retry_host_predicates.previous_hosts"
   }
  ],
  "host_selection_retry_max_attempts": "5"
}

请求将会基于在 retry_on 中配置的内容进行重试。此设置还将对 Envoy 进行配置,以使用 前一个主机重试预测 来允许其选择与前一个失败请求不同的主机,因为同一台主机上的故障通常会持续一段时间,立即重试成功的概率较低。