haproxy简单使用http-翻译自digitalocean

原文链接:https://www.digitalocean.com/community/tutorials/how-to-use-haproxy-to-set-up-http-load-balancing-on-an-ubuntu-vps

准备工作

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>`?&gt;`</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>`&lt;?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>` ?&gt;`</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