异常值检测

异常值检测和剔除是动态确定上游集群中某些数量的宿主是否与其他宿主表现不同,并将其从健康的 负载均衡 集中移除的过程。性能可能沿着不同的轴,例如连续失败、时间成功率、时间延迟等。异常值检测是一种 *被动* 健康检查。Envoy 还支持 主动健康检查。*被动* 和 *主动* 健康检查可以一起或独立启用,并构成整体上游健康检查解决方案的基础。异常值检测是 集群配置 的一部分,它需要过滤器来报告错误、超时和重置。目前,以下过滤器支持异常值检测:HTTP 路由器TCP 代理Redis 代理Thrift 代理

检测到的错误分为两类:外部和本地生成的错误。外部生成的错误是特定于事务的,并且在上游服务器上响应收到的请求而发生。例如,HTTP 服务器返回错误代码 500 或 Redis 服务器返回无法解码的有效负载。这些错误是在 Envoy 成功连接到上游主机后在上游主机上生成的。本地生成的错误是由 Envoy 响应中断或阻止与上游主机通信的事件而生成的。本地生成的错误示例包括超时、TCP 重置、无法连接到指定端口等。

检测到的错误类型取决于过滤器类型。例如,HTTP 路由器 过滤器检测本地生成的错误(超时、重置 - 与连接到上游主机相关的错误),因为它还了解 HTTP 协议,因此它报告 HTTP 服务器返回的错误(外部生成的错误)。在这种情况下,即使与上游 HTTP 服务器的连接成功,与服务器的事务也可能失败。相比之下,TCP 代理 过滤器不了解 TCP 层之上的任何协议,并且只报告本地生成的错误。

在默认配置下 (outlier_detection.split_external_local_origin_errors 为 *false*),本地生成的错误与外部生成的(事务)错误没有区别,都进入同一个桶,并与 outlier_detection.consecutive_5xxoutlier_detection.consecutive_gateway_failureoutlier_detection.success_rate_stdev_factor 配置项进行比较。例如,如果由于超时导致与上游 HTTP 服务器的连接两次失败,然后在成功建立连接后,服务器返回错误代码 500,那么总错误计数将为 3。

注意

对于 TCP 流量,outlier_detection.consecutive_5xx 是正确设置的参数,并且会透明地映射到 TCP 连接失败。

还可以配置异常值检测以区分本地生成的错误和外部生成的(事务)错误。这可以通过 outlier_detection.split_external_local_origin_errors 配置项完成。在这种模式下,本地生成的错误由与外部生成的(事务)错误不同的计数器跟踪,并且可以配置异常值检测器以对本地生成的错误做出反应并忽略外部生成的错误,反之亦然。

重要的是要了解,一个集群可以由多个过滤器链共享。如果一个过滤器链根据其异常值检测类型剔除了一个宿主,那么即使其他过滤器链的异常值检测类型不会剔除该宿主,其他过滤器链也会受到影响。

剔除算法

根据异常值检测的类型,剔除要么内联运行(例如,在连续 5xx 的情况下),要么以指定的时间间隔运行(例如,在定期成功率的情况下)。剔除算法的工作原理如下

  1. 确定一个宿主是异常值。

  2. 它检查以确保被剔除的宿主数量低于允许的阈值(通过 outlier_detection.max_ejection_percent 设置指定)。如果被剔除的宿主数量超过了阈值,则不会剔除该宿主。

  3. 该宿主会被剔除一段时间(以毫秒为单位)。剔除意味着该宿主被标记为不健康,并且在负载均衡器处于 恐慌 场景中之前不会被使用。毫秒数等于 outlier_detection.base_ejection_time 值乘以该宿主被连续剔除的次数。这会导致宿主如果继续失败,则会被剔除更长时间。当剔除时间达到 outlier_detection.max_ejection_time 时,它就不会再增加。当该宿主变得健康时,剔除时间乘数会随着时间的推移而减少。假设该宿主保持健康状态,则大约需要 outlier_detection.max_ejection_time / outlier_detection.base_ejection_time * outlier_detection.interval 秒才能将剔除时间降低到最小值 outlier_detection.base_ejection_time

  4. 被剔除的宿主将在剔除时间满足后自动恢复服务。通常,异常值检测与 主动健康检查 一起使用,以构建全面的健康检查解决方案。

注意

如果也配置了 主动健康检查,则成功的主动健康检查会剔除该宿主并清除所有异常值检测计数器。如果该宿主尚未达到 unhealthy_threshold 次失败的健康检查,则一次成功的健康检查就会剔除该宿主。如果为该宿主设置了 FAILED_ACTIVE_HC 健康标志,则 healthy_threshold 次连续成功的健康检查将剔除该宿主(并清除 FAILED_ACTIVE_HC 标志)。如果您的主动健康检查没有验证数据平面流量,那么在主动健康检查通过但流量失败的情况下,终结点将过早地被剔除。要禁用此选项,请将 outlier_detection.successful_active_health_check_uneject_host 配置标志设置为 false

检测类型

Envoy 支持以下异常值检测类型

连续 5xx

在默认模式下 (outlier_detection.split_external_local_origin_errors 为 *false*),此检测类型会考虑所有生成的错误:本地生成的和外部生成的(事务)错误。

注意

由非 HTTP 过滤器(如 TCP 代理Redis 代理)生成的错误会内部映射到 HTTP 5xx 代码并按此处理。

在拆分模式下 (outlier_detection.split_external_local_origin_errors 为 *true*),此检测类型只考虑外部生成的(事务)错误,而忽略本地生成的错误。如果上游宿主是 HTTP 服务器,则只考虑 5xx 类型的错误(有关例外情况,请参见 连续网关故障)。对于通过 Redis 代理 提供服务的 Redis 服务器,只考虑服务器返回的格式错误的响应。即使响应中包含操作错误(如索引未找到、拒绝访问),但格式正确的响应不会被考虑在内。

如果上游主机返回一定数量的错误,这些错误被视为连续的 5xx 类型错误,则该主机将被剔除。用于剔除所需的连续 5xx 数量由 outlier_detection.consecutive_5xx 值控制。

连续网关故障

在默认模式下 (outlier_detection.split_external_local_origin_errorsfalse) ,此检测类型考虑 5xx 错误的子集,称为“网关错误”(502、503 或 504 状态码)和本地源故障,例如超时、TCP 重置等。

在拆分模式下 (outlier_detection.split_external_local_origin_errorstrue) ,此检测类型考虑 5xx 错误的子集,称为“网关错误”(502、503 或 504 状态码),并且仅受 http 路由器 支持。

如果上游主机返回一定数量的连续“网关错误”(502、503 或 504 状态码),则该主机将被剔除。用于剔除所需的连续网关故障数量由 outlier_detection.consecutive_gateway_failure 值控制。

连续本地源故障

此检测类型仅在 outlier_detection.split_external_local_origin_errorstrue 时启用,并且仅考虑本地源错误(超时、重置等)。如果 Envoy 反复无法连接到上游主机或与上游主机的通信反复中断,则该主机将被剔除。检测各种本地源问题:超时、TCP 重置、ICMP 错误等。用于剔除所需的连续本地源故障数量由 outlier_detection.consecutive_local_origin_failure 值控制。此检测类型受 http 路由器tcp 代理redis 代理 支持。

成功率

基于成功率的异常值检测从集群中的每个主机聚合成功率数据。然后,在给定的时间间隔内,根据统计异常值检测剔除主机。如果主机在聚合时间间隔内的请求量小于 outlier_detection.success_rate_request_volume 值,则不会为该主机计算成功率异常值检测。此外,如果时间间隔内具有最小所需请求量的主机数量小于 outlier_detection.success_rate_minimum_hosts 值,则不会对集群执行检测。

在默认配置模式下 (outlier_detection.split_external_local_origin_errorsfalse) ,此检测类型考虑所有类型的错误:本地和外部源错误。 outlier_detection.enforcing_local_origin_success 配置项被忽略。

在拆分模式下 (outlier_detection.split_external_local_origin_errorstrue) ,本地源错误和外部源(事务)错误将被分别计算和处理。大多数配置项,即 outlier_detection.success_rate_minimum_hostsoutlier_detection.success_rate_request_volumeoutlier_detection.success_rate_stdev_factor 适用于这两种类型的错误,但 outlier_detection.enforcing_success_rate 仅适用于外部源错误,而 outlier_detection.enforcing_local_origin_success_rate 仅适用于本地源错误。

失败百分比

基于失败百分比的异常值检测与成功率检测类似,因为它依赖于集群中每个主机的成功率数据。但是,它不是将这些值与整个集群的平均成功率进行比较,而是将它们与一个扁平的用户配置阈值进行比较。此阈值通过 outlier_detection.failure_percentage_threshold 字段配置。

基于失败百分比的检测的其他配置字段类似于成功率检测的字段。基于失败百分比的检测也遵循 outlier_detection.split_external_local_origin_errors;外部和本地源错误的执行百分比分别由 outlier_detection.enforcing_failure_percentageoutlier_detection.enforcing_failure_percentage_local_origin 控制。与成功率检测一样,如果主机在聚合时间间隔内的请求量小于 outlier_detection.failure_percentage_request_volume 值,则不会对该主机执行检测。如果时间间隔内具有最小所需请求量的主机数量小于 outlier_detection.failure_percentage_minimum_hosts 值,则也不会对集群执行检测。

gRPC

对于 gRPC 请求,异常值检测将使用从 grpc-status 响应标头映射的 HTTP 状态。

剔除事件日志

Envoy 可选择性地生成异常值剔除事件日志。这在日常操作期间非常有用,因为全局统计信息无法提供有关哪些主机被剔除以及原因的足够信息。该日志结构化为 OutlierDetectionEvent 消息 的基于 protobuf 的转储。剔除事件日志是在集群管理器 异常值检测配置 中配置的。

配置参考