如何在 Linux 上使用 HAProxy 配置 HTTP 负载均衡器
对基于 Web 的应用程序和服务的需求不断增加,IT 管理员的负担也越来越重。当面临意外的流量峰值、有机流量增长或硬件故障和紧急维护等内部挑战时,无论如何,您的 Web 应用程序都必须保持可用。即使是现代的开发运营和持续交付实践也会威胁到 Web 服务的可靠性和一致性能。
不可预测性或不一致的性能是您无法承受的。但我们怎样才能消除这些缺点呢?在大多数情况下,适当的负载平衡解决方案就可以完成这项工作。今天我将向您展示如何使用 HAProxy 设置 HTTP 负载均衡器。
什么是 HTTP 负载均衡?
HTTP 负载平衡是一种网络解决方案,负责在托管相同应用程序内容的服务器之间分配传入的 HTTP 或 HTTPS 流量。通过在多个可用服务器之间平衡应用程序请求,负载平衡器可以防止任何应用程序服务器成为单点故障,从而提高整体应用程序可用性和响应能力。它还允许您通过根据不断变化的工作负载添加或删除额外的应用程序服务器来轻松扩展/缩小应用程序部署。
何时何地使用负载平衡?
由于负载均衡器提高了服务器利用率并最大限度地提高了可用性,因此只要服务器开始处于高负载状态,就应该使用它。或者,如果您只是为更大的项目规划架构,那么预先规划负载均衡器的使用是一个好习惯。当您将来需要扩展环境时,它将证明自己很有用。
什么是 HAProxy?
HAProxy 是 GNU/Linux 平台上流行的开源负载均衡器和 TCP/HTTP 服务器代理。 HAproxy 采用单线程事件驱动架构设计,能够轻松处理 10G NIC 线速,并广泛应用于许多生产环境中。其功能包括自动健康检查、可定制的负载均衡算法、HTTPS/SSL 支持、会话速率限制等。
在本教程中我们要实现什么目标?
在本教程中,我们将介绍为 HTTP Web 服务器配置基于 HAProxy 的负载均衡器的过程。
先决条件
您将需要至少一台(最好是两台)Web 服务器来验证负载均衡器的功能。我们假设后端 HTTP Web 服务器已经启动并运行。
在 Linux 上安装 HAProxy
对于大多数发行版,我们可以使用您的发行版的包管理器来安装 HAProxy。
在 Debian 上安装 HAProxy
在 Debian 中,我们需要为 Wheezy 添加向后移植。为此,请在 /etc/apt/sources.list.d
中创建一个名为 backports.list
的新文件,其中包含以下内容:
deb http://cdn.debian.net/debian wheezybackports main
刷新存储库数据并安装 HAProxy。
# apt get update
# apt get install haproxy
在 Ubuntu 上安装 HAProxy
# apt get install haproxy
在 CentOS 和 RHEL 上安装 HAProxy
# yum install haproxy
配置HAProxy
在本教程中,我们假设有两个已启动并运行的 HTTP Web 服务器,IP 地址为 192.168.100.2
和 192.168.100.3
。我们还假设负载均衡器将配置在 IP 地址为 192.168.100.4
的服务器上。
要使 HAProxy 正常工作,您需要更改 /etc/haproxy/haproxy.cfg
中的许多项目。本节描述了这些更改。如果不同 GNU/Linux 发行版的某些配置有所不同,我们将在段落中注明。
1. 配置日志记录
您应该做的第一件事就是为 HAProxy 设置适当的日志记录,这对于将来的调试很有用。日志配置可以在 /etc/haproxy/haproxy.cfg
的 global
部分找到。以下是配置 HAProxy 日志记录的发行版特定说明。
在 CentOS 或 RHEL 上配置日志记录:
要在 CentOS/RHEL 上启用日志记录,请替换:
log 127.0.0.1 local2
和:
log 127.0.0.1 local0
下一步是在 /var/log
中为 HAProxy 设置单独的日志文件。为此,我们需要修改当前的 rsyslog 配置。为了使配置简单明了,我们将在 /etc/rsyslog.d/
中创建一个名为 haproxy.conf
的新文件,其中包含以下内容。
$ModLoad imudp
$UDPServerRun 514
$template Haproxy,"%msg%n"
local0.=info /var/log/haproxy.log;Haproxy
local0.notice /var/log/haproxystatus.log;Haproxy
local0.* ~
此配置将根据 $template 将所有 HAProxy 消息分离到 /var/log
中的日志文件。现在重新启动 rsyslog 以应用更改。
# service rsyslog restart
Debian 或 Ubuntu:
要在 Debian 或 Ubuntu 上启用 HAProxy 日志记录,请替换:
log /dev/log local0
log /dev/log local1 notice
和:
log 127.0.0.1 local0
接下来,要为 HAProxy 配置单独的日志文件,请在 /etc/rsyslog.d/
中编辑名为 haproxy.conf
(在 Debian 中为 49-haproxy.conf
)的文件,其中包含以下内容。
$ModLoad imudp
$UDPServerRun 514
$template Haproxy,"%msg%n"
local0.=info /var/log/haproxy.log;Haproxy
local0.notice /var/log/haproxystatus.log;Haproxy
local0.* ~
此配置将根据 $template 将所有 HAProxy 消息分离到 /var/log
中的日志文件。现在重新启动 rsyslog 以应用更改。
# service rsyslog restart
2. 设置默认值
下一步是设置 HAProxy 的默认变量。在 /etc/haproxy/haproxy.cfg
中找到 defaults
部分,并将其替换为以下配置。
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 20000
contimeout 5000
clitimeout 50000
srvtimeout 50000
建议将上述配置用于 HTTP 负载均衡器,但它可能不是适合您的环境的最佳解决方案。在这种情况下,请随意浏览 HAProxy 手册页来调整它。
3. 网络农场配置
Webfarm 配置定义了可用 HTTP 服务器池。我们的负载均衡器的大部分设置都将放置在这里。现在我们将创建一些基本配置,在其中定义我们的节点。使用以下代码替换从 frontend
部分到文件末尾的所有配置:
listen webfarm *:80
mode http
stats enable
stats uri /haproxy?stats
stats realm Haproxy Statistics
stats auth haproxy:stats
balance roundrobin
cookie LBN insert indirect nocache
option httpclose
option forwardfor
server web01 192.168.100.2:80 cookie node1 check
server web02 192.168.100.3:80 cookie node2 check
listen webfarm *:80
行定义了我们的负载均衡器将侦听的接口。为了本教程的目的,我将其设置为 *
,这使得负载均衡器侦听我们的所有接口。在现实世界中,这可能是不可取的,应该替换为可从互联网访问的界面。
stats enable
stats uri /haproxy?stats
stats realm Haproxy Statistics
stats auth haproxy:stats
上述设置声明我们的负载均衡器统计信息可以在 http://
上访问。通过使用登录名 haproxy
和密码 stats
的简单 HTTP 身份验证来保护访问。这些设置应替换为您自己的凭据。如果您不需要这些统计信息,请完全禁用它们。
以下是 HAProxy 统计信息的示例。

balance roundrobin
行定义了我们将使用的负载平衡类型。在本教程中,我们将使用简单的循环算法,这对于 HTTP 负载平衡来说完全足够了。 HAProxy 还提供其他类型的负载平衡:
leastconn:提供与连接数最少的服务器的连接。
源:对源IP地址进行哈希处理,并将其除以正在运行的服务器的总权重,以决定哪台服务器将接收请求。
uri:URI 的左侧部分(问号之前)经过哈希处理并除以正在运行的服务器的总权重。结果决定哪个服务器将接收请求。
url_param:参数中指定的 URL 参数将在每个 HTTP GET 请求的查询字符串中查找。您基本上可以使用精心设计的 URL 将请求锁定到特定的负载均衡器节点。
hdr(name):将在每个 HTTP 请求中查找 HTTP 标头
并将其定向到特定节点。
cookie LBN insert dependent nocache
行使我们的负载均衡器存储持久性 cookie,这使我们能够查明池中的哪个节点用于特定会话。这些节点 cookie 将以定义的名称存储。在我们的例子中,我使用了LBN
,但您可以指定您喜欢的任何名称。该节点会将其字符串存储为该 cookie 的值。
server web01 192.168.100.2:80 cookie node1 check
server web02 192.168.100.3:80 cookie node2 check
上面的部分是我们的 Web 服务器节点池的定义。每个服务器都用其内部名称表示(例如,web01
、web02
)。 IP 地址和唯一的 cookie 字符串。 cookie 字符串可以定义为您想要的任何内容。我正在使用简单的节点1,节点2 ...节点(n)。
启动HAProxy
完成配置后,就可以启动 HAProxy 并验证一切是否按预期工作。
在 Centos/RHEL 上启动 HAProxy
启用 HAProxy 在启动后启动并使用以下命令将其打开:
# chkconfig haproxy on
# service haproxy start
当然,不要忘记在防火墙中启用端口 80,如下所示。
CentOS/RHEL 7 上的防火墙:
# firewallcmd permanent zone=public addport=80/tcp
# firewallcmd reload
CentOS/RHEL 6 上的防火墙:
将以下行添加到 /etc/sysconfig/iptables
的 :OUTPUT ACCEPT
部分:
A INPUT m state state NEW m tcp p tcp dport 80 j ACCEPT
并重新启动iptables
:
# service iptables restart
在 Debian 上启动 HAProxy
使用以下命令启动 HAProxy:
# service haproxy start
不要忘记通过将以下行添加到 /etc/iptables.up.rules
中来启用防火墙中的端口 80:
A INPUT p tcp dport 80 j ACCEPT
在 Ubuntu 上启动 HAProxy
通过将 /etc/default/haproxy
中的 ENABLED
选项设置为 1
来启用 HAProxy 在启动后启动:
ENABLED=1
启动 HAProxy:
# service haproxy start
并在防火墙中启用端口 80:
# ufw allow 80
测试 HAProxy
要检查 HAproxy 是否正常工作,我们可以执行以下操作。
首先,准备包含以下内容的 test.php
文件:
<?php
header('Content-Type: text/plain');
echo "Server IP: ".$_SERVER['SERVER_ADDR'];
echo "nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR'];
?>
这个 PHP 文件将告诉我们哪个服务器(即负载均衡器)转发了请求,以及哪个后端 Web 服务器实际处理了该请求。
将此 PHP 文件放置在两个后端 Web 服务器的根目录中。现在使用 curl
命令从负载均衡器 (192.168.100.4
) 获取此 PHP 文件。
$ curl http://192.168.100.4/test.php
当我们多次运行此命令时,我们应该看到以下两个输出交替出现(由于循环算法)。
Server IP: 192.168.100.2
X-Forwarded-for: 192.168.100.4
Server IP: 192.168.100.3
X-Forwarded-for: 192.168.100.4
如果我们停止两个后端 Web 服务器之一,curl
命令应该仍然有效,将请求定向到另一个可用的 Web 服务器。
概括
到目前为止,您应该拥有一个完全可操作的负载均衡器,它可以以循环模式向您的 Web 节点提供请求。与往常一样,请随意尝试配置,使其更适合您的基础设施。我希望本教程可以帮助您使您的 Web 项目更具抵抗力和可用性。
正如大多数人已经注意到的那样,本教程仅包含一个负载均衡器的设置。这意味着我们刚刚用另一个故障点替换了一个故障点。在现实场景中,您应该部署至少两个或三个负载均衡器来应对可能发生的任何故障,但这超出了本教程的范围。
如果您有任何问题或建议,请随时在评论中提出,我会尽力回答或建议。