准备工作
3个节点
1. node1
hostname:haproxy
os:ubuntu
ip:10.0.0.100
2.node2
hostname lamp1
ip:10.0.0.1
3.node3
hostname lamp2
ip:10.0.0.2
安装HAProxy
1.直接使用apt-get安装
apt-get install haproxy
2.安装完成之后,我们打开/etc/default/haproxy把ENABLED设置为1
配置HAProxy
1.进入到/etc/haproxy里新建haproxy.cfg
2.打开haproxy.cfg,我们一部分一部分的向里面加入
2.1 首先加入如下配置
global
log 127.0.0.1 local0 notice
maxconn 2000
user haproxy
group haproxy
log指令的意思是告诉haproxy把系统日志发送到哪一台的syslog服务器,ubuntu里面的sysslog当然是运行着的,但是它没有绑定任何ip地址,我们将会在后面修改rsyslog的配置文件
maxconn的意思当然时说明了同一时间最大的连接数了,这个数字可以随便改
user和group是给正在运行haproxy进程的制定用户和用户组,这个就不要改变他了
2.2 然后加入defaluts块
defaluts
log global
mode http
option httplog
option dontlognull
retries 3
option redispath
timeout connect 5000
timeout client 10000
timeout server 10000
在这个块里,我们指定了默认的值。
timeout connect选项指定了最大的连接时间
timeout client和server设置的值表示如果服务器或者客户端在这段时间没有进行任何tcp处理,那么将会被断开,HAProxy推荐两个使用相同的值
retries指令用来设置重连的次数
option redispatch会开启当链接断掉的时候重分发session,所以如果后面的服务挂掉了,session粘滞不会存在。
2.3 下面配置listen
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为appname监听80端口,appname仅仅是个用来区分引用的名字。
stats指令用来开启连接状态统计页面,这个通过HTTP Basic authentication保证安全,它时stats auth指定的
stats uri就是这个统计页面的url地址
balance指令指定了一个负载均衡算法,可以有的选项有roundrobin/static-rr/leastconn/source/uri/url_param
server指令时来申明一个后端服务器,语法如下
server <name> <address>[:port] [param*]
name主要是写入日志用,方便我们跟踪日志,这里有更多的参数,在这篇文章中我们只使用check和cookie这两个参数
check参数时开启健康检查,检查服务器是否正常
2.4 好了,我们现在配置好了可以使用下面的命令开启它
service haproxy start
测试负载均衡
1.创建php文件打印处服务器ip和客户端ip
<?php header(‘Content-Type: text/plain’); `
<pre>`echo "Server IP: ".$_SERVER['SERVER_ADDR']; `</pre> <pre>`echo "\nClient IP: ".$_SERVER['REMOTE_ADDR'];`</pre> <pre>` echo "\nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR']; `</pre> <pre>`?>`</pre> <pre>`我们访问haproxy所在的ip地址`</pre> <pre>`第一次访问`</pre>
Server IP: 172.17.0.5
Client IP: 172.17.0.3 X-Forwarded-for: 172.17.42.1 第二次访问
Server IP: 172.17.0.4
Client IP: 172.17.0.3 X-Forwarded-for: 172.17.42.1 <span style="color: #ff0000;">注:我没有多个机器,所以我使用的docker容器来做实验,这个是我自己跑出来的结果</span>
从上面我们看到haproxy轮番的把我们的请求放到两个后端服务器上,X-Forwarded-for是你自己客户端
2.模拟服务器挂掉的情况
我们现在模拟服务器挂掉,首先把一个服务关掉,我关掉172.17.0.4的服务
> service apache2 stop
继续访问
连续访问两次都是如下结果
> Server IP: 172.17.0.5
Client IP: 172.17.0.3 X-Forwarded-for: 172.17.42.1 我们达到了服务负载和容错的功能
## Session Stickness
如果拟的web应用需要用户登陆(就是你的服务使用到了session),这种负载均衡可能就会遇到问题,因为session是和具体的服务器相关的,haproxy会把用户随机搞到不同的服务器上,服务器就带状态了,就不好搞成分布式了,如果是这种需求,那么我们必须保证用户会被分配到他第一次访问的服务器上去,不然就会乱套,haproxy可以通过设置cookie来标记所使用的服务器来达到这种效果。
下面我们增加一个session.php文件来阐述下这个是如何工作的
> <pre>`<?php header('Content-Type: text/plain'); `</pre>
<pre>`session_start(); `</pre> <pre>`if(!isset($_SESSION['visit'])) { `</pre> <pre>`echo "This is the first time you're visiting this server"; `</pre> <pre>`$_SESSION['visit'] = 0; `</pre> <pre>`} `</pre> <pre>`else `</pre> <pre>`echo "Your number of visits: ".$_SESSION['visit']; `</pre> <pre>`$_SESSION['visit']++; echo "\nServer IP: ".$_SERVER['SERVER_ADDR']; `</pre> <pre>`echo "\nClient IP: ".$_SERVER['REMOTE_ADDR']; echo "\nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR']."\n"; print_r($_COOKIE);`</pre> <pre>` ?>`</pre> <pre>`上面的代码就在apache的服务器上对用户增加了session,会记录你使用这个session多少次`</pre> <pre>`下面,我们就要使用haproxy在cookie中增加我们的东西了`</pre> <pre>`我们默认所有到haproxy的请求在http头里都包含set-cookie的字段,我们在这里面存服务器信息`</pre> <pre>第一步就是在配置文件中,在listen块的下面增加cookie指令</pre>
`cookie SRVNAME insert `<pre>`server lamp1 10.0.0.1:80 cookie S1 check `</pre> <pre>`server lamp2 10.0.0.2:80 cookie S2 check`</pre> <pre>`我们重启haproxy`</pre> <pre>`下面使用curl访问`</pre>
`curl -i http://172.17.0.3/session.php结果如下
HTTP/1.1 200 OK Date: Fri, 16 Jan 2015 14:12:00 GMT Server: Apache/2.4.7 (Ubuntu) X-Powered-By: PHP/5.5.9-1ubuntu4.5 Set-Cookie: PHPSESSID=q29dmd1eusk0gs1ja9qcq0paj5; 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: 134 Connection: close Content-Type: text/plain Set-Cookie: SRVNAME=S1; path=/ This is the first time you're visiting this server Server IP: 172.17.0.4 Client IP: 172.17.0.3 X-Forwarded-for: 172.17.42.1 Array ( )这个时第一次访问,为了看到我们刚刚的SRVNAME=S1,我们把上面的Set-cookies的头作为参数访问加入SRVNAME=S1(当然你要是浏览器,可以F12召唤神兽直接看)
curl -i http://172.17.0.3/session.php --cookie "PHPSESSID=0juvu9ir7bvm4agiivfc5pvg11; SRVNAME=S1"
结果如下
HTTP/1.1 200 OK Date: Fri, 16 Jan 2015 14:12:15 GMT Server: Apache/2.4.7 (Ubuntu) X-Powered-By: PHP/5.5.9-1ubuntu4.5 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: 174 Connection: close Content-Type: text/plain Your number of visits: 1 Server IP: 172.17.0.4 Client IP: 172.17.0.3 X-Forwarded-for: 172.17.42.1 Array ( [PHPSESSID] => q29dmd1eusk0gs1ja9qcq0paj5 [SRVNAME] => S1 )在执行一下
HTTP/1.1 200 OK Date: Fri, 16 Jan 2015 14:12:18 GMT Server: Apache/2.4.7 (Ubuntu) X-Powered-By: PHP/5.5.9-1ubuntu4.5 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: 174 Connection: close Content-Type: text/plain Your number of visits: 2 Server IP: 172.17.0.4 Client IP: 172.17.0.3 X-Forwarded-for: 172.17.42.1 Array ( [PHPSESSID] => q29dmd1eusk0gs1ja9qcq0paj5 [SRVNAME] => S1 )可以看到我们解决了这个Session strickness