1

我目前在单个负载均衡器下的两个 EC2 节点上运行 REST API 应用程序。与来自多个 IP 的少量流量的标准负载平衡方案不同,我仅从几个 IP 获得大量流量。因此,我希望来自每个单独 IP 的请求分布在所有可用节点之间。

然而,即使关闭了会话粘性,情况似乎也并非如此。查看我的日志,几乎所有请求都发送到一台服务器,而我最小的客户端发送到辅助节点。这是有害的,因为对我的服务的请求可能会持续长达 30 秒,而失去该主节点将意味着不成比例的请求被杀死。

我如何指示我的 ELB 循环处理每个客户的单独请求?

4

4 回答 4

0

你不能。ELB 使用不可配置的循环算法。你可以做些什么来缓解(而不是解决)这个问题,就是向你的 ELB 添加额外的服务器和/或使你的 ELB 发起的健康检查请求更加频繁。

于 2012-07-06T15:57:50.033 回答
0

我在使用 Amazon ELB 时遇到过类似的问题,但对我来说,事实证明 HTTP 客户端使用了 Connection: keep-alive。换句话说,来自同一客户端的请求通过同一连接提供服务,因此它不会在服务器之间切换。我不知道您使用哪个服务器,但可能会关闭保持活动状态,强制客户端为每个请求建立新连接。对于具有大量数据的请求,这可能是一个很好的解决方案。如果您有大量带有小数据的请求,则可能会对性能产生负面影响。

于 2012-08-25T22:48:56.310 回答
0

当您在不同的可用区中拥有两个实例时,可能会发生这种情况。

当一个 ELB 在单个可用区中处理多个实例时,它将在实例之间循环请求。

当两个实例位于两个不同的可用区时,ELB 的工作方式是创建两个服务器(elb 服务器),每个服务器都有自己的 IP,并通过 DNS 平衡负载。

当您的客户端向 DNS 询问您服务器的 IP 地址时,它会收到两个(或更多)响应。然后客户端选择一个 IP 并缓存它(操作系统通常会这样做)。除非您控制客户端,否则您对此无能为力。

当您的问题是两个实例位于不同的可用区时,解决方案可能是每个可用区中至少有两个实例。然后,一台 ELB 服务器将处理两台服务器之间的循环,并且只有一个 IP,因此当服务器发生故障时,它对客户端是透明的。

PS:ELB 创建更多具有唯一 IP 的服务器的另一种情况是,当您在单个可用区中有很多服务器时,单个 ELB 服务器无法处理所有负载并将其分配给连接的服务器。然后再次创建一个新服务器来连接额外的实例,并使用 DNS 和多个 IP 分配负载。

于 2012-10-03T09:21:21.600 回答
0

我明白你来自哪里。但是,我认为你应该从不同的角度来处理这个问题。您的问题似乎与负载不平衡这一事实没有特别关系。假设您确实解决了这个平衡问题。您仍然会丢失大量请求。我不知道您的客户如何连接到您的服务,因此我无法详细说明您如何解决问题,但您可能希望考虑改进代码以使其更健壮并计划连接到被丢弃。任何连接超过 30 秒的服务都不应该依赖连接不被丢弃。回到 TCP/UDP 套接字的时代,在构建失败方面做了大量工作,不知何故,这些工作在今天的 HTTP 世界中已经丢失了。

我想说的是,如果您编写客户用来连接的代码,构建代码以使其更加健壮并通过重试处理故障。开始执行重试后,您需要确保 API 调用是原子的,并在必要时使用事务。

最后,我会回答你原来的问题。亚马逊的 ELB 是循环的,即使来自同一台计算机/IP 地址。如果您的客户端始终连接到同一台服务器,则很可能是浏览器或缓存响应的代码。如果他们不直接从浏览器访问您的 REST API,大多数语言都允许您获取给定主机名的 ip 列表。这些 ip 将是负载均衡器的 ip,您可以将列表打乱,然后每次使用顶部条目。例如,您可以使用以下 PHP 代码将请求随机发送到不同的负载均衡器。

public function getHostByName($domain) {
    $ips = gethostbynamel($domain);
    shuffle($ips);
    return $ips[0];
}
于 2012-07-07T16:51:17.010 回答