如何从单个客户端向多个节点发出ELB转发请求?

时间:2012-07-06 14:19:01

标签: amazon-web-services amazon-elb

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

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

如何指示我的ELB针对每个客户的个别请求进行循环?

4 个答案:

答案 0 :(得分:0)

你做不到。 ELB使用不可配置的循环算法。您可以采取哪些措施来缓解(而不是解决)此问题,即在ELB中添加额外的服务器和/或更频繁地启动ELB启动的运行状况检查请求。

答案 1 :(得分: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];
}

答案 2 :(得分:0)

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

答案 3 :(得分:0)

当两个实例位于不同的可用区域时,可能会发生这种情况。

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

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

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

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

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