如何处理瞬时故障?¶
在服务网格中使用 Envoy 的一个最大优势就是它让服务从实现复杂的弹性功能解脱出来,如熔断、异常检测以及重试,这些让服务应对实际情况时更具弹性,常见的诸如滚动升级、动态基础设施变更以及网络故障。Envoy 中实现的上述功能不仅仅提高了服务可用性和韧性,而且在行为和观测性方面带来了一致性。
这部分将从一个较高层次来解释 Envoy 支持的配置以及如何一起使用这些功能来处理这些场景。
熔断¶
熔断 是分布式系统非常重要的一环。熔断可以让应用程序配置故障阈值,以确保最大限度的安全,允许组件快速失败然后尽可能快的恢复正常。使用正确的熔断阈值有助于节省那些浪费在请求等待(超时)或者非必要的请求重试中的资源。对于在 Envoy 中实现的熔断来讲 ,一个主要的优势是熔断限制可以被应用在网络层。 .. _common_configuration_transient_failures_retries:
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 进行配置,以使用 前一个主机重试预测 来允许其选择与前一个失败请求不同的主机,因为同一台主机上的故障通常会持续一段时间,立即重试成功的概率较低。