天天看点

haproxy配置详解以及动静分离的实现

一、前面已经介绍过关于haproxy的工作特性了,本文主要介绍下haproxy如何来实现web应用的动静分离的,主要思路就是通过frontend段中定义acl访问控制,把符合静态内容的请求归类到一个acl,符合动态的请求归类到另外一个acl,backend段中定义接收请求的静态内容和动态内容的服务器,然后通过use_backend调用定义的acl即可。

二、实验环境:

192.168.30.116 OS:Centos6.4 x86_64  haproxy.luojianlong.com

192.168.30.117 OS:Centos6.4 x86_64  static.luojianlong.com

192.168.30.119 OS:Centos6.4 x86_64  dynamic.luojianlong.com

haproxy version:haproxy-1.4.24

拓扑图如下:

<a href="http://s3.51cto.com/wyfs02/M02/23/A3/wKiom1M88sHiF5ofAAEnJ_tv2Oo134.jpg" target="_blank"></a>

在haproxy server上安装haproxy,这里使用yum安装

1

<code>[root@haproxy ~]</code><code># yum -y install haproxy</code>

在static server,dynamic上安装httpd和php

2

<code>[root@static ~]</code><code># yum -y install httpd</code>

<code>[root@dynamic ~]</code><code># yum -y install httpd php</code>

分别启动static,dynamic的httpd,测试本地访问是否正常

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<code>[root@static ~]</code><code># service httpd start</code>

<code>[root@static ~]</code><code># ss -naptl | grep :80</code>

<code>LISTEN     0      128                      :::80                      :::*      </code><code>users</code><code>:((</code><code>"httpd"</code><code>,24245,5),(</code><code>"httpd"</code><code>,24247,5),(</code><code>"httpd"</code><code>,24248,5),(</code><code>"httpd"</code><code>,24249,5),(</code><code>"httpd"</code><code>,24250,5),(</code><code>"httpd"</code><code>,24251,5),(</code><code>"httpd"</code><code>,24252,5),(</code><code>"httpd"</code><code>,24253,5),(</code><code>"httpd"</code><code>,24254,5))</code>

<code>[root@static ~]</code><code># echo "static.luojianlong.com" &gt;&gt; /var/www/html/index.html</code>

<code>[root@static ~]</code><code># curl 192.168.30.117</code>

<code>static.luojianlong.com</code>

<code>[root@dynamic ~]</code><code># service httpd start</code>

<code>[root@dynamic ~]</code><code># ss -anplt | grep :80</code>

<code>LISTEN     0      128                      :::80                      :::*      </code><code>users</code><code>:((</code><code>"httpd"</code><code>,13702,5),(</code><code>"httpd"</code><code>,13704,5),(</code><code>"httpd"</code><code>,13705,5),(</code><code>"httpd"</code><code>,13706,5),(</code><code>"httpd"</code><code>,13707,5),(</code><code>"httpd"</code><code>,13708,5),(</code><code>"httpd"</code><code>,13709,5),(</code><code>"httpd"</code><code>,13710,5),(</code><code>"httpd"</code><code>,13711,5))</code>

<code>[root@dynamic ~]</code><code># vi /var/www/html/index.php</code>

<code>&lt;?php</code>

<code>echo</code> <code>"dynamic.luojianlong.com"</code>

<code>?&gt;</code>

<code>[root@dynamic ~]</code><code># curl -I http://192.168.30.119/index.php</code>

<code>HTTP</code><code>/1</code><code>.1 200 OK</code>

<code>Date: Thu, 03 Apr 2014 05:39:23 GMT</code>

<code>Server: Apache</code><code>/2</code><code>.2.15 (CentOS)</code>

<code>X-Powered-By: PHP</code><code>/5</code><code>.3.3</code>

<code>Connection: close</code>

<code>Content-Type: text</code><code>/html</code><code>; charset=UTF-8</code>

访问都正常

下面开始配置haproxy

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

<code>[root@haproxy ~]</code><code># cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak</code>

<code>[root@haproxy ~]</code><code># vi /etc/haproxy/haproxy.cfg</code>

<code>global</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 </code> 

<code>    </code><code>log         127.0.0.1 local2</code>

<code>    </code><code>chroot      </code><code>/var/lib/haproxy</code>

<code>    </code><code>pidfile     </code><code>/var/run/haproxy</code><code>.pid</code>

<code>    </code><code>maxconn     4000</code>

<code>    </code><code>user        haproxy</code>

<code>    </code><code>group       haproxy</code>

<code>    </code><code>daemon</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                </code> 

<code>    </code><code>stats socket </code><code>/var/lib/haproxy/stats</code>

<code>defaults</code>

<code>    </code><code>mode                    http</code>

<code>    </code><code>log                     global</code>

<code>    </code><code>option                  httplog</code>

<code>    </code><code>option                  dontlognull</code>

<code>    </code><code>option http-server-close</code>

<code>    </code><code>option forwardfor       except 127.0.0.0</code><code>/8</code>

<code>    </code><code>option                  redispatch</code>

<code>    </code><code>retries                 3</code>

<code>    </code><code>timeout http-request    10s</code>

<code>    </code><code>timeout queue           1m</code>

<code>    </code><code>timeout connect         10s</code>

<code>    </code><code>timeout client          1m</code>

<code>    </code><code>timeout server          1m</code>

<code>    </code><code>timeout http-keep-alive 10s</code>

<code>    </code><code>timeout check           10s</code>

<code>    </code><code>maxconn                 3000</code>

<code>listen stats</code>

<code>    </code><code>mode http</code>

<code>    </code><code>bind 0.0.0.0:1080</code>

<code>    </code><code>stats </code><code>enable</code>

<code>    </code><code>stats hide-version</code>

<code>    </code><code>stats uri     </code><code>/haproxyadmin</code><code>?stats</code>

<code>    </code><code>stats realm   Haproxy\ Statistics</code>

<code>    </code><code>stats auth    admin:admin</code>

<code>    </code><code>stats admin </code><code>if</code> <code>TRUE</code>

<code>frontend http-</code><code>in</code>

<code>    </code><code>bind *:80</code>

<code>    </code><code>log global</code>

<code>    </code><code>option httpclose</code>

<code>    </code><code>option logasap</code>

<code>    </code><code>option dontlognull</code>

<code>    </code><code>capture request  header Host len 20</code>

<code>    </code><code>capture request  header Referer len 60</code>

<code>    </code><code>acl url_static       path_beg       -i </code><code>/static</code> <code>/images</code> <code>/javascript</code> <code>/stylesheets</code>

<code>    </code><code>acl url_static       path_end       -i .html .jpg .jpeg .gif .png .css .js</code>

<code>    </code><code>acl url_dynamic      path_end       -i .php .jsp</code>

<code>    </code><code>use_backend static_servers          </code><code>if</code> <code>url_static</code>

<code>    </code><code>use_backend dynamic_servers         </code><code>if</code> <code>url_dynamic</code>

<code>backend static_servers</code>

<code>    </code><code>balance roundrobin</code>

<code>    </code><code>server imgsrv1 192.168.30.117:80 check maxconn 6000</code>

<code>#   server imgsrv2 192.168.30.118:80 check maxconn 6000</code>

<code>backend dynamic_servers</code>

<code>    </code><code>balance </code><code>source</code>

<code>    </code><code>server websrv1 192.168.30.119:80 check maxconn 1000</code>

<code>#   server websrv2 192.168.30.120:80 check maxconn 1000</code>

stats enable:启用基于程序编译时默认设置的统计报告,不能用于“frontend”区段;

stats hide-version:启用统计报告并隐藏HAProxy版本报告,不能用于“frontend”区段。默认情况下,统计页面会显示一些有用信息,包括HAProxy的版本号,然而,向所有人公开HAProxy的精确版本号是非常有风险的,因为它能帮助恶意用户快速定位版本的缺陷和漏洞;

stats realm:启用统计报告并高精认证领域,不能用于“frontend”区段。haproxy在读取realm时会将其视作一个单词,因此,中间的任何空白字符都必须使用反斜线进行转义。此参数仅在与“stats auth”配置使用时有意义;

stats scope:启用统计报告并限定报告的区段,不能用于“frontend”区段。当指定此语句时,统计报告将仅显示其列举出区段的报告信息,所有其它区段的信息将被隐藏。如果需要显示多个区段的统计报告,此语句可以定义多次。需要注意的是,区段名称检测仅仅是以字符串比较的方式进行,它不会真检测指定的区段是否真正存在;

stats auth:启用带认证的统计报告功能并授权一个用户帐号,其不能用于“frontend”区段;

stats admin:在指定的条件满足时启用统计报告页面的管理级别功能,它允许通过web接口启用或禁用服务器,不过,基于安全的角度考虑,统计报告页面应该尽可能为只读的。此外,如果启用了HAProxy的多进程模式,启用此管理级别将有可能导致异常行为;

option http-server-close:允许服务器端关闭连接;

option dontlognull:访问内容为空的不记录日志;

option redispatch:在session失败后,是否允许重新分配;

retries:用于haproxy到后端server连接失败时重试次数;

option httplog:启用记录HTTP请求、会话状态和计时器的功能;

option forwardfor:允许在发往服务器的请求首部中插入“X-Forwarded-For”首部;

ACL语法格式:

acl &lt;aclname&gt; &lt;criterion&gt; [flags] [operator] &lt;value&gt; ...

&lt;aclname&gt;:ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl;

&lt;criterion&gt;:测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整;而有些测试标准也可以需要为其在&lt;value&gt;之前指定一个操作符[operator];

[flags]:目前haproxy的acl支持的标志位有3个:

        -i:不区分&lt;value&gt;中模式字符的大小写;

        -f:从指定的文件中加载模式;

        --:标志符的强制结束标记,在模式中的字符串像标记符时使用;

&lt;value&gt;:acl测试条件支持的值有以下四类:

        整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为           通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;

        字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;如果在模式首部出现了-i,可以在         其之前使用“--”标志位;

        正则表达式:其机制类同字符串匹配;

        IP地址及网络地址  

path_beg &lt;string&gt;:用于测试请求的URL是否以&lt;string&gt;指定的模式开头;

path_end &lt;string&gt;:用于测试请求的URL是否以&lt;string&gt;指定的模式结尾;

支持的负载均衡算法:

roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;

static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制;

leastconn:新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重;

source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性;

uri:对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性;

url_param:通过&lt;argument&gt;为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可以使用hash-type修改此特性;

hdr(&lt;name&gt;):对于每个HTTP请求,通过&lt;name&gt;指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分,以降低hash算法的运算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性;

hash-type &lt;method&gt;

定义用于将hash码映射至后端服务器的方法;其不能用于frontend区段;可用方法有map-based和consistent,在大多数场景下推荐使用默认的map-based方法。

map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时,大多数连接将会被重新派发至一个与此前不同的服务器上,对于缓存服务器的工作场景来说,此方法不甚适用。

consistent:hash表是一个由各服务器填充而成的树状结构;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。

接下来,启动haproxy

<code>[root@haproxy ~]</code><code># service haproxy start</code>

<code>Starting haproxy:                                          [  OK  ]</code>

<code>[root@haproxy ~]</code><code># ss -anptl | grep :80</code>

<code>LISTEN     0      128                       *:80                       *:*      </code><code>users</code><code>:((</code><code>"haproxy"</code><code>,20436,6))</code>

<a href="http://s3.51cto.com/wyfs02/M02/23/A4/wKiom1M8_lGgGILtAAcwdnD_TDI817.jpg" target="_blank"></a>

发现定义的static_servers和dynamic_servers已经正常工作

haproxy的管理界面支持直接禁用backend_server,使客户端无法访问:

<a href="http://s3.51cto.com/wyfs02/M00/23/A5/wKioL1M8_o-TFrF7AAHNf4WpYUQ527.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M02/23/A5/wKioL1M8_z3R9VTTAABE_NRbwjc525.jpg" target="_blank"></a>

发现访问的192.168.30.117,为静态内容服务器

<a href="http://s3.51cto.com/wyfs02/M02/23/A5/wKioL1M8_7WgJioHAABCZctrMxw758.jpg" target="_blank"></a>

发现访问的192.168.30.119,为动态内容服务器

到此已经实现了动静分离的效果。

     本文转自ljl_19880709 51CTO博客,原文链接:http://blog.51cto.com/luojianlong/1389630,如需转载请自行联系原作者