AWS Application Load balancer select 如何成为目标组中的目标?如何负载平衡 websocket 流量?

How does AWS Application Load balancer select a target within a target group? How to load balance the websocket traffic?

我有一个 AWS 应用程序负载均衡器来分配 http(s) 流量。

问题 1:

假设我有一个包含 2 个 EC2 实例的目标组:micro 和 xlarge。显然,它们可以处理不同的流量级别。负载均衡器是根据实例大小按比例管理流量还是只是循环管理?如果只使用round robin,不考虑其他因素,那么它并不是真正的负载均衡,因为在某些时候,micro instance 会受到流量的影响,而xlarge 会饿死。

问题 2:

假设我的目标组有 2 个 EC2 实例,两者大小相同。但是我的服务没有使用经典的 http request/response 流程。它使用 HTTP websockets,即客户端只发出一次 HTTP 请求,以建立套接字,然后保持套接字打开更长时间,发送和接收消息(例如聊天服务)。假设我的负载均衡器使用循环法,并且两个 EC2 实例都连接了 1000 个客户端。现在假设其中一个 EC2 实例出现故障,并且 1000 个连接的客户端断开了它们的套接字连接。该实例迅速恢复并准备好再次接受 websocket 调用。掉线的 1000 个客户端正在尝试重新连接。现在,如果负载均衡器使用纯循环法,我最终将有 1500 个客户端连接到实例 #1,500 个客户端连接到实例 #2,因此没有真正正确地平衡负载。

基本上,我试图找出是否正在使用一些更高级的逻辑来 select 组中的目标,或者它只是一个天真的循环法 selection。如果它只是循环,那么我怎样才能真正平衡 websocket 连接负载?

Websockets 以 http 或 https 连接开始,因此负载均衡器可以将它们分派到服务器。一旦服务器接受了 http 连接,服务器和客户端都会“升级”连接以使用 websocket 协议。然后他们保持连接打开以用于 websocket 流量。就负载均衡器而言,连接只是一个持久的 http 连接。

当服务器与客户端有 websocket 连接时关闭服务器需要您的应用程序重试丢失的连接。连接失败时重新连接是 websocket 客户端编程中最棘手的部分之一。如果没有重新连接逻辑,您的应用程序就不可能健壮。

AWS 的负载均衡器 没有关于其背后服务器功能的内置知识。您已经观察到它向大型和小型服务器平等地发送请求。这可以压倒小的。

我通过在我的服务器中构建一个 /healthcheck 端点 来管理它。这是一个简单明了的 https://example.com/heathcheck 网页。您可以在页面上放置一些内容,宣布当前打开了多少个 websocket 连接,或其他任何内容。不要用密码保护它或需要会话才能访问它。

我的 /healthcheck 端点,每当命中时,都会测量服务器负载。我只使用当前 websocket 连接数,但您可以使用任何您想要的指标。我将当前负载与为每台服务器配置的负载阈值进行比较。例如,在微型实例上我可以处理 20 个打开的 websocket,而在生产实例上我可以处理 400 个。

如果服务器负载过高,我的端点会返回 503 http error status 及其内容。 503 通常表示“我超载了,请稍后再试”。它也可以表示“当我所有的连接都关闭时,我将关闭。请不要再使用我进行任何连接。”

然后我configure the load balancer每隔几分钟在服务器池中的所有服务器上执行这些健康检查(AWS 将池称为“目标组”) .健康检查操作检测“不健康”的服务器并暂时将它们排除在轮换之外。 (运行状况检查还检测崩溃的服务器,这很好。)

大规模生产设置需要此负载均衡器运行状况检查。

综上所述,如果您的池中的所有服务器实例彼此具有大致相同的容量,您将获得最佳结果。