7

我在 AWS ALB 后面有一个应用程序/目标,并且想对它将接收的 TCP 连接数设置一个硬上限。

如果我理解正确,ALB 目标可以是

  • 健康——ALB 将流量路由到目标。

或者

  • 不健康 - ALB 不会将流量路由到目标。此外,它会尽快耗尽/取消注册/重新启动目标(我在文档中找不到这个,但这是我观察到的行为)。

理想情况下,当达到连接上限时,我会将目标置于第三种状态,即“不要杀死我,但也不要将流量路由给我”(因此我会产生更多目标以满足需求)。

没有这样的第三种状态,但是否有另一种方法来限制连接数?

4

1 回答 1

4

关于这个问题本身有一个主要的误解,所以我将首先解决这个问题

ALB 目标可能 [...] 不健康 - ALB 不会将流量路由到目标。此外,它会尽快耗尽/取消注册/重新启动目标(我在文档中找不到这个,但这是我观察到的行为)。

这不是真正发生的事情。

而 ALB 是一个负载均衡器:它将请求路由到目标,根据您可以在一定程度上配置的一些路由逻辑。

它还将执行健康检查,用于从 ALB 的角度确定目标是健康的还是不健康的。

这是一种误解:当目标被认为不健康时,ALB唯一会做的就是停止向它发送新请求。就这样。

ALB 本身没有能力 (1) 取消注册或 (2) 重新启动目标。事实上,它自己会继续执行健康检查,只要目标再次恢复健康,它就会再次开始发送流量。

您描述的您观察到的行为也可能不完全是发生的事情。您说目标已注销并重新启动。除非您有一些令人难以置信的自定义(极不可能),否则目标不会重新启动,但它们已被替换。这是一个巨大的差异。

让我们假设这是实际发生的行为。

发生这种情况的原因几乎可以肯定是有一个与 ALB 集成的AutoScaling Group(它是 AWS 上最常见的设计之一)。AutoScaling Group 可以将运行状况检查与 ALB 集成(即 ASG 使用目标运行状况的 ALB 报告)。当ASG确定一个实例不健康时(例如,通过与 ALB 的集成),然后ASG 继续替换,以便它保持许多实例处于健康状态(等于DesiredCapacity)。


现在,回到问题 - 简而言之,在 ALB 级别,您无法对目标将接收的连接数设置硬性上限

实际上,您需要 (1) 首先防止这种饱和情况发生,并且 (2) 决定它发生时该怎么做。

为了防止这种情况发生,您需要确保始终有足够的实例来处理当前的流量,以及从您可以检测到流量增加到新实例可以启动并投入使用之间的预计流量增加。例如,您可以使用基于每个目标上的平均连接数的警报并触发 AutoScaling(在走这条路线之前,确保“连接数”确实是最佳扩展指标非常重要) . 检查您可以以多快的速度将新实例投入使用,并检查您需要维护多少过度配置,以便在检测到负载增加与新实例准备就绪之间有足够的时间。

发生时该怎么办?您在这里主要有两个一般选择:

  • 您的目标可以在可能“降级”的情况下接受和处理请求(即,您处理的请求比您的规范多,因此它们都可能变慢,或者由于下游问题而失败等);

  • 或者您可以快速拒绝该请求(但仔细检查它不是 ALB 请求!您应该继续接受并处理这些请求)并向调用者返回一条错误消息(也称为减载)。

在任何一种情况下,您都应该决定是要“等待”,还是要启动一个进程来添加新实例以处理额外的负载。这个决定通常归结为确定流量增加是持续性的还是暂时的、短暂的峰值的可能性有多大。

您不应该做的一件事是为此目的搞乱健康检查。如果您拒绝来自 ALB 的运行状况检查请求,它会将实例归类为不健康,如果您有 ASG(您应该),ASG 将终止该实例(导致剩余实例的负载更大,而该实例替换)。此外,对于 ALB 来说, “我很健康但已经饱和”的情况与“我真的有问题,我需要被替换”是无法区分的。

最后一点:请记住,ALB 并不是真正处理“连接”,而是处理“请求”(即,它是更高级别的抽象)。这意味着“连接数”现在可能是一个很好的扩展指标,因为 ALB 可以并且很可能会将来自大量客户端的请求多路复用到目标的较少数量的连接中。也就是说,如果 ALB 从 10 个不同的客户端接收 TCP 连接,它可能只打开 5 个(或任何其他数量)到目标的连接,并仅通过这 5 个连接发送来自所有 10 个客户端的请求。

于 2021-05-04T20:49:20.153 回答