负载均衡问题一直是管理大型系统的热点问题。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间,避免任何单一资源的过载,因此解决此问题对于性能至关重要。在本文中,我们将介绍可能的问题解决方案。
为了更好地了解WS负载平衡,让我们深入一下TCP套接字背景。默认情况下,单个服务器可以处理65,536个套接字连接,因为它是可用的TCP端口的最大数量。因此,作为WS连接具有TCP性质,每个WS客户端都需要一个端口,我们可以肯定地说,websocket连接的数量也受到限制。
其实这是一个半真相。服务器可以处理每个IP地址65,536个套接字。因此,可以通过向服务器添加额外的网络接口来轻松扩展数量。同时,跟踪服务器上存在多少连接非常重要。
一旦超出限制,您可能会遇到其他TCP连接的许多问题(例如,无法通过ssh连接到服务器)。因此,限制应用程序代码中每个节点的WS连接是一个好主意。当我们处理websockets时,我们在应用程序中也是一样的。
一旦我们得到了主要的限制和克服它的方法,我们继续进行负载平衡。下面我将介绍我们在一个项目中尝试过的3种方法。请注意,所有系统部件已部署到AWS,一些提示和提示仅适用于Amazon配置。
实现负载平衡的最简单方法就是使用弹性负载平衡器AWS提供的。可以将ELB切换到TCP模式,从而实现任何类型的TCP连接(包括websockets)的负载平衡。这种方法给出:
基本上,对于大多数常见的情况来说,这是一个很好的解决方案,直到你的负载飞速增长。在这种情况下,ELB变得太慢,无法建立新的连接。有可能联系亚马逊并要求他们“预热”ELB,但是由于负载测试的目的,当我们需要快速建立数千个WS连接并且由于系统的可用性而为我们的客户而不是我们的选择。
我们已经尝试过HAProxy作为负载均衡器。但是要使HAProxy正常工作,请记住我们上面已经讨论过的端口限制问题。为了使HAProxy处理65k以上的连接,我们应该通过以下步骤:
1.创建一堆私有IP地址。要做到这一点,选择您的Amazon Instance - >操作 - >网络 - >管理专用IP地址。也就是增加了3个IP地址:192.168.1.1,192.168.1.2,192.168.1.3。只要记住,IP应该在与真实应用服务器相同的子网中;
2.通过SSH连接到您的HAProxy实例并运行以下命令:
$> ifconfig eth0:1 192.168.1.1 $> ifconfig eth0:2 192.168.1.2 $> ifconfig eth0:3 192.168.1.3
这将向实例添加3个虚拟网络接口;
3.配置HAProxy。以下是haproxy.cfg3个Erlang节点接受WS连接的文件。
listen erlang_front :8888 mode http balance roundrobin timeout connect 1s timeout queue 5s timeout server 3600s option httpclose option forwardfor server erlang-1 192.168.0.1:8888 source 192.168.1.1 server erlang-2 192.168.0.2:8888 source 192.168.1.2 server erlang-3 192.168.0.3:8888 source 192.168.1.3
现在,HAProxy可以处理超过65,536个websocket连接,并且可以通过添加虚拟网络接口轻松增加连接的限制。此外,它可以建立新的连接相当快。
这种方法似乎是可行的,尽管存在以下缺点:
我们很好,这些缺点,但更简单的解决方案被实施。这是可能的,因为我们已经有一些代码实现了,我们的系统设计允许我们使用自定义的方法。
要继续前进,请查看显示系统架构的下图。
我们有一个JavaScript客户端应用程序,一个负责用户授权的认证应用程序和具有主要应用程序功能的Erlang应用程序。流程如下:
这是我们的基本流程略有修改。我们向Erlang应用程序添加了一个简单的模块来跟踪每个Erlang节点上的Websocket连接数。由于Erlang的“分布式”性质,每个节点都知道其他节点的连接。
所以我们可以选择一个连接较少的节点。我们拿这个节点的公共IP地址,然后发送回auth应用程序。然后,认证应用程序将该IP与令牌一起发送回客户端。客户端建立与接收的IP地址和令牌的WS连接。所以最终图如下所示:
现在我们可以:
此外: