即使运行状况检查失败,什么原因会导致应用程序负载均衡器将流量转发到未就绪的实例?

即使运行状况检查失败,什么原因会导致应用程序负载均衡器将流量转发到未就绪的实例?

我有一个 AWS Elastic beanstalk 环境,该环境可以从 2 个实例扩展到 3 个实例,并配置了应用程序负载均衡器。负载均衡器配置了 HTTP 健康检查,以查找 200 响应。

当环境自动扩展到 3 个实例时,新实例在准备就绪之前就开始接收流量。如果我手动检查健康检查 URL,我可以看到 1/3 次它会返回 404,因为新实例尚未准备就绪。应用程序的其他 URL 也会出错,1/3 次因为它们不存在。

据我了解,健康检查 URL 的全部目的就是处理这个问题。那么,是什么原因导致了这个问题呢?

一些可能相关的信息:

  • 该实例需要很长时间才能准备就绪,因为它是一个需要安装 ARR 的 ASP.Net 应用程序。
  • 在增强型健康检查概述中,两个工作实例被列为“严重”,尽管它们工作正常。它们列出了几个 5xx 错误,我不确定为什么,而且由于发送给它们的流量很少,因此占流量的很大比例。奇怪的是,尚未准备好的新实例被标记为“正常”。我不认为增强型健康检查决定了负载均衡器何时认为实例是健康的,但也许我错了?
  • 当我尝试联系 AWS 支持时,代理向我发送了大量有关不可变环境更新和滚动更新的信息。据我了解,这与配置更改或进行新部署时如何将新实例上线有关,这与负载平衡运行状况检查和自动扩展不同,因此无关。但是,也许我误解了,代理未能说明为什么这与这种情况有关。

答案1

如果我手动检查健康检查 URL,我会发现有三分之一的时间它会返回 404,因为新实例尚未准备好。

当您碰巧通过平衡器访问其中一个健康节点时,健康检查 URL 对健康节点起作用的事实并不一定与平衡器访问该节点进行健康检查时健康检查 URL 正常工作相同。

现代 HTTP 版本要求Host每个传入请求中都存在一个标头,并且平衡器会将 HTTP 主机标头设置为实例的私有 IP 地址以进行健康检查请求,但会在正常请求中传递浏览器设置的值 - 并且您的浏览器会将相同的标头设置为您用于访问平衡器的主机名。

如果您(以及您的服务器/框架/应用程序)没有考虑到这一点,并且您的服务器对它们采取了不同的处理方式,那么尽管您尝试手动检查时发现它们有效,但实际上您的所有实例可能始终无法通过健康检查。当出现“所有目标均不健康”的情况时,ALB 会假设最安全的做法是将流量转发到所有实例,就好像它们都是健康的一样(这是一种故障安全但不一定是直观的设计),这可以准确解释您所看到的情况。

如果目标组仅包含不健康的注册目标,则负载均衡器节点会将请求路由到其不健康的目标。

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html

相关内容