如何使用HAProxy在Ubuntu VPS上设置HTTP负载平衡

关于HAProxy

HAProxy(高可用性代理)是一个开源负载均衡器,可以负载平衡任何TCP服务。 它特别适合于HTTP负载平衡,因为它支持会话持久性和第7层处理。

通过引入共享的专用网络中DigitalOcean HAProxy的可配置为前端负载均衡通过私人网络连接2 VPS。

序幕

我们将在这里使用三个VPS(Droplet):

Droplet 1 - 负载平衡器
主机名:haproxy
操作系统:Ubuntu
公共IP:1.1.1.1
私人IP:10.0.0.100

Droplet 2 - 节点1
主机名:lamp1
操作系统:LAMP在Ubuntu上
私人IP:10.0.0.1

Droplet 2 - Node 2
主机名:lamp2
操作系统:LAMP在Ubuntu上
私人IP:10.0.0.2

安装HAProxy

使用apt-get命令来安装HAProxy的。

apt-get install haproxy

我们需要通过init脚本启动HAProxy。

nano /etc/default/haproxy

设置ENABLED选项设置为1

ENABLED=1

要检查此更改是否正确执行HAProxy的init脚本,不带任何参数。 您应该看到以下内容。

root@haproxy:~# service haproxy
Usage: /etc/init.d/haproxy {start|stop|reload|restart|status}

配置HAProxy

我们将移动默认配置文件并创建自己的配置文件。

mv /etc/haproxy/haproxy.cfg{,.original}

创建和编辑新的配置文件:

nano /etc/haproxy/haproxy.cfg

让我们开始通过块添加配置到此文件:

global
    log 127.0.0.1 local0 notice
    maxconn 2000
    user haproxy
    group haproxy

log指令提及到日志消息syslog服务器将被发送。 在Ubuntu rsyslog已经安装并运行,但它不监听任何IP地址。 我们将稍后修改rsyslog的配置文件。

maxconn指令指定的前端并发连接数。 默认值是2000 ,应该根据自己的VPS'的配置进行调整。

usergroup的指令改变HAProxy的过程中指定的用户/组。 这些不应该改变。

defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    retries 3
    option redispatch
    timeout connect  5000
    timeout client  10000
    timeout server  10000

我们在此部分中指定默认值。 要修改的值是不同的timeout指令。 connect选项指定的最长时间等待尝试连接到一个VPS成功。

clientserver超时时,客户端或服务器预计将确认或在TCP过程中发送数据应用。 HAProxy的建议将设置clientserver超时为相同的值。

retries指令设置的重试次数,以连接失败后一个VPS执行。

option redispatch使会议重新分配的连接失败的情况下。 因此,如果VPS下降,会话粘性被覆盖。

listen appname 0.0.0.0:80
    mode http
    stats enable
    stats uri /haproxy?stats
    stats realm Strictly\ Private
    stats auth A_Username:YourPassword
    stats auth Another_User:passwd
    balance roundrobin
    option httpclose
    option forwardfor
    server lamp1 10.0.0.1:80 check
    server lamp2 10.0.0.2:80 check

这包含前端和后端的配置。 我们正在配置HAProxy的监听端口80 appname这仅仅是用于识别应用的名称。 stats指令启用连接统计页面,并保护它HTTP基本身份验证使用由指定的凭据stats auth指令。

这个页可以在提及的网址观看stats uri所以在这种情况下,它是http://1.1.1.1/haproxy?stats ;
此页的演示可以在这里查看

balance指令指定负载均衡算法使用。 可用的选项轮循( roundrobin ),静态轮循( static-rr ),最少连接( leastconn ),来源( source ),URI( uri )和URL参数( url_param )。

每个算法的信息可以从获得的官方文件

server指令声明后端服务器,语法是:

server <name> <address>[:port] [param*]

我们在此处提到的名称将显示在日志和警报中。 很多paratmeters通过这个指令支持,我们将使用checkcookie在这篇文章中的参数。 check选项启用健康检查的VPS否则,VPS是
始终认为可用。

配置完成后,启动HAProxy服务:

service haproxy start

测试负载平衡和故障转移

要测试此设置,请在所有Web服务器(后端服务器 - 这里是LAMP1和LAMP2)上创建一个PHP脚本。

/var/www/file.php

<?php
header('Content-Type: text/plain');
echo "Server IP: ".$_SERVER['SERVER_ADDR'];
echo "\nClient IP: ".$_SERVER['REMOTE_ADDR'];
echo "\nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR'];
?>

现在我们将使用curl并请求这个文件多次。

> curl http://1.1.1.1/file.php

Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X

> curl http://1.1.1.1/file.php

Server IP: 10.0.0.2
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X

> curl http://1.1.1.1/file.php

Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X

注意这里HAProxy如何交替切换LAMP1和LAMP2之间的连接,这就是Round Robin的工作原理。 我们在这里看到的客户端IP负载平衡器和的私有IP地址X-Forwarded-For头就是你的IP。

要查看故障切换的工作原理,请转到Web服务器并停止服务:

lamp1@haproxy:~#service apache2 stop

发送请求与curl再次看到的东西是如何工作的。

会话粘性

如果您的Web应用程序根据用户的登录会话(哪个应用程序不提供)提供动态内容,那么由于VPS之间的连续切换,访问者将会遇到奇怪的事情。 会话粘性确保访客坚持到服务他们的第一请求的VPS。 这可以通过用cookie标记每个后端服务器。

我们将使用以下PHP代码演示会话粘性的工作原理。

/var/www/session.php

<?php
header('Content-Type: text/plain');
session_start();
if(!isset($_SESSION['visit']))
{
        echo "This is the first time you're visiting this server";
        $_SESSION['visit'] = 0;
}
else
        echo "Your number of visits: ".$_SESSION['visit'];

$_SESSION['visit']++;

echo "\nServer IP: ".$_SERVER['SERVER_ADDR'];
echo "\nClient IP: ".$_SERVER['REMOTE_ADDR'];
echo "\nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR']."\n";
print_r($_COOKIE);
?>

此代码创建一个PHP会话 ,并显示在一个会话的页面浏览数。

Cookie插入方法

在这种方法中,从HAProxy的到客户端的所有响应将包含Set-Cookie:头与后端服务器作为其cookie值的名称。 因此,前进的客户端(网络浏览器)将包括此cookie及其所有请求,HAProxy将根据cookie值将请求转发到正确的后端服务器。

对于这种方法,你将需要添加cookie指令,并修改server下指令listen

   cookie SRVNAME insert
   server lamp1 10.0.0.1:80 cookie S1 check
   server lamp2 10.0.0.2:80 cookie S2 check

这将导致HAProxy的添加Set-Cookie:头用一个cookie命名SRVNAME有作为其值S1S2基于其后端回答的请求。 一旦这被添加重新启动服务:

service haproxy restart

并使用curl检查是如何工作的。

> curl -i http://1.1.1.1/session.php
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:11:22 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Set-Cookie: PHPSESSID=l9haakejnvnat7jtju64hmuab5; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 143
Connection: close
Content-Type: text/plain
Set-Cookie: SRVNAME=S1; path=/

This is the first time you're visiting this server
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
)

这是我们做的第一个请求,它是由LAMP1回答,因为我们可以从看到Set-Cookie: SRVNAME=S1; path=/ Set-Cookie: SRVNAME=S1; path=/ 现在,模仿什么网页浏览器将下一个请求做的,我们这些Cookie添加使用的要求--cookie 参数卷曲。

> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=l9haakejnvnat7jtju64hmuab5;SRVNAME=S1;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:11:45 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 183
Connection: close
Content-Type: text/plain

Your number of visits: 1
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.87.127
Array
(
    [PHPSESSID] => l9haakejnvnat7jtju64hmuab5
    [SRVNAME] => S1
)

> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=l9haakejnvnat7jtju64hmuab5;SRVNAME=S1;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:11:45 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 183
Connection: close
Content-Type: text/plain

Your number of visits: 2
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.87.127
Array
(
    [PHPSESSID] => l9haakejnvnat7jtju64hmuab5
    [SRVNAME] => S1
)

这两个请求都由LAMP1提供,会议得到了妥善维护。 如果您希望web服务器上的所有文件具有粘性,则此方法很有用。

Cookie前缀方法

在另一方面,如果你想只对特定的Cookie粘性或者不希望有会话粘性一个单独的cookie,该prefix的选择是给你的。

要使用此方法,请使用以下cookie指令:

cookie PHPSESSID prefix

PHPSESSID可以用自己的cookie的名称所取代。 所述server指令保持相同的先前的配置。

现在让我们看看这是如何工作的。

> curl -i http://1.1.1.1/session.php
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:36:27 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Set-Cookie: PHPSESSID=S1~6l2pou1iqea4mnhenhkm787o56; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 143
Content-Type: text/plain

This is the first time you're visiting this server
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
)

注意如何server的cookie S1被前缀到会话cookie。 现在,让我们用这个cookie发送两个请求。

> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=S1~6l2pou1iqea4mnhenhkm787o56;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:36:45 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 163
Content-Type: text/plain

Your number of visits: 1
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
    [PHPSESSID] => 6l2pou1iqea4mnhenhkm787o56
)

> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=S1~6l2pou1iqea4mnhenhkm787o56;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:36:54 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 163
Content-Type: text/plain

Your number of visits: 2
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
    [PHPSESSID] => 6l2pou1iqea4mnhenhkm787o56
)

我们可以清楚地看到,两个请求都是由LAMP1服务的,会话是完美的工作。

为HAProxy配置日志记录

当我们开始配置HAProxy的,我们添加了一行: log 127.0.0.1 local0 notice其中将syslog信息发送到本地主机的IP地址。 但是默认情况下,Ubuntu上的rsyslog不监听任何地址。 所以我们必须这样做。

编辑rsyslog的配置文件。

nano /etc/rsyslog.conf

添加/编辑/取消注释以下行:

$ModLoad imudp
$UDPServerAddress 127.0.0.1
$UDPServerRun 514

现在rsyslog现在将UDP端口514上运行的地址为127.0.0.1,但所有的消息HAProxy的必去/var/log/syslog ,所以我们必须把它们分开。

为HAProxy日志创建规则。

nano /etc/rsyslog.d/haproxy.conf

将以下行添加到它。

if ($programname == 'haproxy') then -/var/log/haproxy.log

现在重新启动rsyslog服务:

service rsyslog restart

此写入所有HAProxy的消息和访问日志/var/log/haproxy.log

Keepalive在HAProxy

根据listen指令,我们使用option httpclose增加了一个Connection: close标头。 这告诉客户端(Web浏览器)在收到响应后关闭连接。

如果您想要启用HAProxy的保持有效指示,更换option httpclose符合:

option http-server-close
timeout http-keep-alive 3000

明智地设置保持活动超时,以便几个连接不会耗尽负载均衡器的所有资源。

测试Keepalive

保活可以使用被测试curl通过在同一时间发送多个请求。 在以下示例中将省略不必要的输出:

> curl -v http://1.1.1.1/index.html http://1.1.1.1/index.html
* About to connect() to 1.1.1.1 port 80 (#0)
*   Trying 1.1.1.1... connected
> GET /index.html HTTP/1.1
> User-Agent: curl/7.23.1 (x86_64-pc-win32) libcurl/7.23.1 OpenSSL/0.9.8r zlib/1.2.5
> Host: 1.1.1.1
> Accept: */*
>
......[Output omitted].........
* Connection #0 to host 1.1.1.1 left intact
* Re-using existing connection! (#0) with host 1.1.1.1
* Connected to 1.1.1.1 (1.1.1.1) port 80 (#0)
> GET /index.html HTTP/1.1
> User-Agent: curl/7.23.1 (x86_64-pc-win32) libcurl/7.23.1 OpenSSL/0.9.8r zlib/1.2.5
> Host: 1.1.1.1
> Accept: */*
>
.......[Output Omitted].........
* Connection #0 to host 1.1.1.1 left intact
* Closing connection #0

在此输出中,我们必须寻找行: Re-using existing connection! (#0) with host 1.1.1.1 Re-using existing connection! (#0) with host 1.1.1.1 ,这表明卷曲用的相同的连接,使后续请求。

提交者: Jesin一个
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏