使用HAProxy进行第4层负载平衡
说明
第4层负载平衡是在多个服务器之间平衡网络流量的最简单方法。它的简单性意味着用最少的硬件实现闪电般的快速平衡。但是,这种简单性带来了局限性。这种平衡方法最大的缺点是每个Web服务器必须托管完全相同的内容。否则,每位用户以及每次有人访问内容时,用户体验都会改变。
当收到域的传入请求时,它首先到达平衡器。负载平衡器的工作是将请求转发到后端中的Web服务器之一。如图所示,如果应用程序将内容存储在数据库中,则每个Web服务器必须连接到相同的数据库。
在将请求转发给用户的任何Web服务器处理完请求后,该服务器将直接对用户作出响应。但是,由于负载平衡器始终接收传入的请求,因此用户的下一个HTTP请求可能会落在其他后端Web服务器上。通常,这不是问题,除非应用程序允许用户登录。这可以通过使用cookie创建持久连接来解决,它可以告诉负载均衡器我们需要将请求发送到哪个后端服务器。
当然,并非所有Web应用程序都需要除第4层平衡之外的任何其他功能。例如,一个流量大的博客可能不需要更多。另一个示例是我们使用自己的注册域名开发并发布的简单应用程序。
本教程学习如何为应用程序创建简单的第4层平衡器。
准备工作
本教程假定我们已将HAProxy部署到单独的服务器上。如果尚未安装,请阅读在CentOS 6上部署HAProxy负载均衡器。
创建浮动IP地址
浮动IP地址是大多数负载平衡器使用的术语。它实际上是添加到物理网络接口的添加IP地址。这不是绝对必要的,因为我们可以使用负载平衡器的IP地址。但是,当我们平衡多个不同的应用程序时,这成为必需。
- 通过复制现有接口并在文件名的末尾添加冒号(:)和0值来创建新的网络接口。我们将在本教程的第一个界面中添加浮动IP。
cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0:0
- 在文本编辑器中打开新文件。
- 修改接口名称,将其从eth0更改为eth0:0,如下例所示。当然,如果要将浮动IP添加到第二个网络接口eth1,则名称将改为eth1:0。如果要添加第二个浮动IP地址,则将最后一个值加1,使其为eth1:1.
DEVICE=eth0:0 TYPE=Ethernet ONBOOT=yes NM_CONTROLLED=no BOOTPROTO=none IPADDR=172.30.0.30 PREFIX=24 IPV4_FAILURE_FATAL=yes IPV6INIT=no NAME="System eth0:0"
- 保存更改并退出文本编辑器。
- 重新启动网络服务以初始化浮动IP。
services network restart
- 或者,我们可以先关闭物理接口,然后再重新启动。
ifdown eth0
ifup eth0
- 使用ifconfig命令验证新接口是否处于联机状态并分配了浮动IP。输出应类似于以下示例。
eth0 Link encap:Ethernet HWaddr 00:0C:29:E9:C0:05 inet addr:172.30.0.25 Bcast:172.30.0.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fee9:c005/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:27 errors:0 dropped:0 overruns:0 frame:0 TX packets:32 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2316 (2.2 KiB) TX bytes:3244 (3.1 KiB) eth0:0 Link encap:Ethernet HWaddr 00:0C:29:E9:C0:05 inet addr:172.30.0.30 Bcast:172.30.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
创建一个虚拟服务器
负载平衡器上下文中的虚拟服务器是一个IP地址,用于侦听负载平衡群集的传入连接。通常,将浮动IP分配给虚拟服务器。虚拟服务器收到连接后,会将其转发到负载平衡群集或者组中的服务器到后端服务器。我们通过在HAProxy配置文件的全局上下文下添加前端上下文来定义虚拟服务器。
- 在文本编辑器中打开HAProxy配置文件。 CentOS中的默认位置是/etc/haproxy/haproxy.cfg。
- 创建一个虚拟服务器并为其分配浮动IP地址。我们将其称为虚拟服务器webapp1.
frontend webapp1 bind 172.30.0.30:80 default_backend webapp1-servers
绑定 |
---|
虚拟服务器将侦听传入连接的IP地址和端口。这可以是负载平衡器上物理网络接口的IP地址、浮动IP地址或者星形()。使用意味着它将监听所有网络接口 |
服务器组请求的名称将转发到 |
后端服务器群集
现在,我们将为虚拟服务器配置后端集群。这是我们在其中放置有关实际服务器(实际托管我们的内容的服务器)的信息的地方。后端集群的名称与前端上下文的default_backend选项定义的名称相同。
- 为虚拟服务器webapp1创建后端服务器组。
backend webapp1-servers
- 定义负载平衡算法。我们将使用轮询。
backend webapp1-servers balance roundrobin
- 将模式设置为http。
backend webapp1-servers balance roundrobin mode tcp
模式 |
---|
设置实例的运行模式或者协议。可用值包括:tcp、http和health。Tcp用于第4层的平衡,而http用于第7层 |
- 添加托管Web应用程序的真实服务器。我们将在示例中添加三个。每个人都在端口80上托管应用程序。
backend webapp1-servers balance roundrobin mode tcp server webserver1 192.168.1.200:80 server webserver2 192.168.1.201:80 server webserver3 192.168.1.202:80
- 将更改保存到haproxy配置文件。
- 如果HAproxy正在运行,请重新加载配置文件。
service haproxy restart
- 如果HAproxy没有运行,请启动HAProxy。
service haproxy start
平衡算法
轮循round-robin
每个服务器根据其权重依次使用。当服务器的处理时间保持均匀分布时,这是最流畅,最公平的算法。该算法是动态的,这意味着可以为例如慢速启动动态调整服务器权重。
最小连接leastconn
连接数最少的服务器接收该连接。循环在具有相同负载的服务器组内执行,以确保将使用所有服务器。建议在预计会话时间很长的地方(例如LDAP,SQL,TSE等)使用此算法,但不适用于使用HTTP等短会话的协议。该算法是动态的,这意味着可以为例如慢速启动动态调整服务器权重。
来源source
源IP地址经过哈希处理,然后除以运行中服务器的总权重,以指定将接收请求的服务器。这样可以确保相同的客户端IP地址将始终与同一服务器连接,只要没有服务器出现故障即可。如果哈希结果由于正在运行的服务器数量发生更改而发生变化,则许多客户端将被定向到其他服务器。此算法通常在TCP模式下使用,该模式下不能插入cookie。它也可以在Internet上用于为拒绝会话Cookie的客户端提供最大努力的粘性。该算法是静态的,这意味着动态更改服务器的权重将无效。
uri
URI的左侧部分(问号之前)被散列并除以正在运行的服务器的总权重。结果指定哪个服务器将接收请求。这样可以确保只要没有服务器出现故障,相同的URI将始终定向到同一服务器。它与代理缓存和防病毒代理一起使用,以最大程度地提高缓存命中率。请注意,此算法只能在HTTP后端中使用。该算法是静态的,这意味着动态更改服务器的权重将无效。
url_param
与uri相似,只是在哈希中使用了URL参数。这是WordPress和其他内容管理系统使用的永久链接类型URL的理想选择。
健康检查
当负载平衡群集中的服务器不可用时,我们不希望将流量转发到该服务器。运行状况检查是一种自动发现停止响应的服务器的方法。通过在后端的服务器中添加check选项来启用运行状况检查,如以下示例所示。
backend webapp1-servers balance roundrobin mode tcp server webserver1 192.168.1.200:80 check server webserver2 192.168.1.201:80 check server webserver3 192.168.1.202:80 check
服务器维护
每台服务器在生命周期的某个时刻都需要某种形式的维护。为了使服务器脱机以进行维护并防止流量在脱机时转发到该服务器,我们可以使用禁用选项。
backend webapp1-servers balance roundrobin mode tcp server webserver1 192.168.1.200:80 check server webserver2 192.168.1.201:80 check server webserver3 192.168.1.202:80 check disabled