如何处理瞬时故障?

在服务网格中使用 Envoy 的最大优势之一是,它使服务免于实现复杂的弹性功能,例如断路器、异常检测和重试,这些功能使服务能够应对滚动升级、动态基础设施和网络故障等现实情况。在 Envoy 中实现这些功能不仅提高了服务的可用性和弹性,而且在行为和可观察性方面带来了一致性。

本节将从高层面上解释 Envoy 支持的配置以及如何将这些功能一起使用来处理这些情况。

断路器

断路器 是分布式系统的重要组成部分。断路器允许应用程序配置故障阈值,以确保安全的最大值,使组件能够快速失败并尽快施加反压。应用正确的断路器阈值有助于节省资源,否则这些资源将浪费在等待请求(超时)或不必要地重试请求上。Envoy 中断路器实现的主要优势之一是断路器限制是在网络层应用的。

重试

自动 请求重试 是确保服务弹性的另一种方法。请求重试通常应该用于防止瞬时故障。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,reset-before-request,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 使用 先前主机重试谓词,它允许 Envoy 选择与先前请求失败的主机不同的主机,因为通常情况下,同一主机的故障很可能持续一段时间,而立即重试成功的可能性较小。