Linux集群之haproxy简介及应用


一、haproyx简介

  HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在时下的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上。

 

  HAProxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space)实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

 

  HAProxy是免费、极速且可靠的用于为TCP和基于HTTP应用程序提供高可用、负载均衡和代理服务的解决方案,尤其适用于高负载且需要持久连接或7层处理机制的web站点。

 

二、haproxy工作位置

技术分享

 

三、haproxy安装及配置文件详解

3.1 安装haproxy

  在CentOS 6.6 系统中HAProxy已经被收录在安装树中了,在配置好yum源之后直接使用yum install haproxy就能实现安装。

yum install haproxy  -y

3.2 haproxy配置文件详解

  在安装完haproxy程序之后使用rpm-ql haproxy查看安装完所生成的文件,生成的文件比较的少,haproxy的配置文件在/etc/haproxy/haproxy.cfg。

[root@node-04 haproxy]# egrep -v"#|^$" haproxy.cfg 
global      #全局配置
   log         127.0.0.1 local2    #日志文件存放路径,指明为syslog服务器,最多可以定义两个
   chroot      /var/lib/haproxy    #haproxy的工作目录
   pidfile     /var/run/haproxy.pid    #pid文件存放位置
   maxconn     4000                #设定每个haproxy进程所接受的最大并发连接数,其等同于命令行选项“-n”;“ulimit -n”自动计算的结果正是参照此参数设定的;
   user        haproxy     #指定haproxy身份运行haproxy程序
   group       haproxy     #指定haproxy组身份运行haproxy程序
   daemon          #让haproxy以守护进程的方式工作于后台,其等同于“-D”选项的功能,当然,也可以在命令行中以“-db”选项将其禁用;
   stats socket /var/lib/haproxy/stats #指明haproxy运行时socket文件存放位置
defaults    #提供frontend、backend、listen的公共配置信息段
   mode                    http    #haproxy的工作模式,有tcp和http
   log                     global  #日志文件从global承继
   option                  httplog #启动记录http请求、会话状态和计时器的功能
   option                  dontlognull #不记录空日志
   option http-server-close        #启动和禁用服务器端关闭HTTP连接的功能,服务器连接关闭功能主要是在长连接上使用;
   option forwardfor       except127.0.0.0/8  #允许在发往服务器的请求首部中插入“X-Forwarded-For”首部
   option                  redispatch      #开启或禁用如果某一个连接发生了错误是不是需要重启调度;
   retries                 3       #重次次数
   timeout http-request    10s     #等待客户端发送报文超时时长
   timeout queue           1m      #连接队列等待的超时时长
   timeout connect         10s     #等待上游服务器响应haproxy发送报文过程的超时时间
   timeout client          1m      
   timeout server          1m
   timeout http-keep-alive 10s     #设置保护连接的超时时间
   timeout check           10s     #设置健康状态额外的超时时间
   maxconn                 3000    #设定一个前端的最大并发连接数,因此,其不能用于backend区段。
frontend main *:5000   #用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接。
   acl url_static       path_beg       -i /static /images /javascript/stylesheets #定义一个ACL规则
   acl url_static       path_end       -i .jpg .gif .png .css .js
   use_backend static          ifurl_static   #匹配ACL规则的将会使用“static”的后端服务器
   default_backend             app         #在没有匹配的"use_backend"规则时为实例指定使用的默认后端
backend static  #用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器。
   balance     roundrobin      #定义负载均衡调度算法
   server      static 127.0.0.1:4331check #为后端声明一个server,因此,不能用于defaults和frontend区段。“check”表示做健康状态检查
backend app
   balance     roundrobin
   server  app1 127.0.0.1:5001 check
   server  app2 127.0.0.1:5002 check
   server  app3 127.0.0.1:5003 check
   server  app4 127.0.0.1:5004 check


3.3 负载均衡调度算法

类型说明
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

通过<argument>为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可以使用hash-type修改此特性;
hdr(<name>)对于每个HTTP请求,通过<name>指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.magedu.com来说,仅计算magedu字符串的hash值)以降低hash算法的运算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性;


四、haproxy配置实践之启动haproxy状态统计报告页面

4.1 启动haproxy状态统计报告

  haproxy的状态统计报告的功能非常的强大,可以标记后端服务器不可用,因此应该监听在一个内网地址的特定端口上,在访问此页面时要进行认证,认证成功才能访问。

在haproxy.cfg配置文件中添加如下内容:

listen stats
    mode http
    bind 172.16.9.84:7009
    stats enable
    stats hide-version
    stats uri   /haproxyadmin?stats
    stats realm HAProxy\Statistics
    stats auth  admin:admin
    stats admin if  TRUE


4.2 解释状态统计报告段配置信息

listen stats   

    modehttp

    bind172.16.9.84:7009   #监听在指定的套接字上

    statsenable         #开启状态统计报告

    statshide-version     #隐藏状态统计报告中的haproxy版本信息

    statsuri   /haproxyadmin?stats #指定状态统计报告的访问URI地址

    statsrealm HAProxy\ Statistics #认证时的提示信息,空格要使用“\”进行转意

    statsauth  admin:admin     #认证时的用户名:密码

    statsadmin if  TRUE        #在指定的条件满足时启用统计报告页面的管理级别功能,它允许通过web接口启用或禁用服务器,不过,基于安全的角度考虑,统计报告页面应该尽可能为只读的。


4.3 启动haproxy

[root@node-04 ~]# service haproxy start
Starting haproxy:                               [  OK  ]


4.4 检查监听端口

[root@node-04 ~]# ss -tanp|grep 7009
LISTEN    0      128           172.16.9.84:7009             *:*      users:(("haproxy",1465,7))


4.5 访问测试

  在浏览器中输入http://172.16.9.84:7009/haproxyadmin?stats进行访问,在认证成功后的页面如下

技术分享

 

五、haproxy配置实践之负载均衡Web服务

  用户请求haproxy反向代理服务器,实现负载均衡的效果,你也可以根据上面的调度算法根据业务的需求进行调整,实验拓扑;

技术分享

5.1 haproxy节点的配置内容

[root@node-04 haproxy]# egrep -v"#|^$" haproxy.cfg 
global
   log         127.0.0.1 local2
   chroot      /var/lib/haproxy
   pidfile     /var/run/haproxy.pid
   maxconn     4000
   user        haproxy
   group       haproxy
   daemon
   stats socket /var/lib/haproxy/stats
defaults
   mode                    http
   log                     global
   option                  httplog
   option                 dontlognull
   option http-server-close
   option forwardfor       except127.0.0.0/8
   option                  redispatch
   retries                 3
   timeout http-request    10s
   timeout queue           1m
   timeout connect         10s
   timeout client          1m
   timeout server          1m
   timeout http-keep-alive 10s
   timeout check           10s
   maxconn                 3000
frontend main *:80
   default_backend            websrvs
listen stats
    modehttp
    bind172.16.9.84:7009
    statsenable
    statshide-version
    statsuri   /haproxyadmin?stats
    statsrealm HAProxy\ Statistics
    statsauth  admin:admin
    statsadmin if  TRUE
backend websrvs
   balance     roundrobin
   server  web1 172.16.9.81:8080check 
   server  web2 172.16.9.83:8080check


5.2 各Web节点的测试页面的内容

Web节点监听在8080的端口上,如节点的测试页面如下:

Web-01节点测试页面:

<h1>Real Server node-01</h1>


Web-02节点测试页面:

<h1>Real Server node-02</h1>


5.3 重新加载haproxy的配置信息

service haproxy reload


5.4 访问测试

在浏览器http://172.16.9.84中访问或使用curl命令进行测试,将会出现轮询的效果

[root@node-04 haproxy]# curlhttp://172.16.9.84
<h1>Real Server node-01</h1>
[root@node-04 haproxy]# curlhttp://172.16.9.84
<h1>Real Server node-02</h1>


 

六、haproxy配置实践之基本Cookie绑定会话

  在上面的配置中实现的在访问Web服务器时能轮询的访问后端服务器,但在特定的场景中有时需要将用户的会话保持至同一台后端服务器时,就可以使用基本Cookie的会话绑定。

  cookie为当客户端第一次访问服务器时,服务器生成一个随机的cookie,为此用户会话使用,用户浏览器收到cookie信息以后,将会保存在自己浏览器缓存中,而后在向同一个站点请求任何资源时都会附加会话标识信息。

  haproxy的cookie参数,是用于客户端在后端的upstream服务器端之间通信时,如果upstream 设置了cookie给客户端的话,haproxy是将会修改、添加在原有cookie的基础上附加一些信息上去,以实现基本haproxy来追踪客户端的通信信息

6.1 修改haproxy.cfg文件中backned段的代码

backend websrvs
   balance     roundrobin
   cookie WEBID insert indirect nocache
   server  web1 172.16.9.81:8080check cookie web1
   server  web2 172.16.9.83:8080check cookie web2


6.2 配置信息解释

cookie WEBID insert indirect nocache

  启用基于cookie后端服务器黏性的功能,insert表示内插方式去将当前haproxy调度出来的WEBID信息插入到客户端的cookie信息中去,并通知不要缓存用户的敏感信息。

  如果用户请求时第一次被调度至web1服务器,web1会回一个cookie信息给客户端,haproxy会把web1这个服务器自己的WEBID附加在cookie上,当客户端第二次请求发出web资源请求时,haproxy通过分析就知道此前就是由web1这台服务器响应的,所以haproxy就把此请求定向至web1。这样haproxy就能追踪此前每一个server作出的响应。

6.3 访问测试

  在浏览器中按F12打开开发人员工具,进行查看Cookie的信息,在浏览器输入http://172.16.9.84/,当再次刷新时就被定位至同一台RealServer了,查看Cookie信息中包含了在HAProxy插入的WEBID=XX的HTTP首部请求信息。

Cookie:pma_lang=zh_CN;pma_collation_connection=utf8_general_ci; pma_mcrypt_iv=fmN5yE3kUyc%3D;WEBID=web1


 

七、haproxy配置实践之动静分离

  当客户端请求静态资源时haproxy将轮询的把用户的请求调度至后端服务器,请求的动态资源将调度至Web-02服务器上。

7.1 实验拓扑

技术分享

7.2 haproxy的配置信息

[root@node-04 haproxy]# egrep -v"#|^$" haproxy.cfg 
global
   log         127.0.0.1 local2
   chroot      /var/lib/haproxy
   pidfile     /var/run/haproxy.pid
   maxconn     4000
   user        haproxy
   group       haproxy
   daemon
   stats socket /var/lib/haproxy/stats
defaults
   mode                    http
   log                     global
   option                  httplog
   option                 dontlognull
   option http-server-close
   option forwardfor       except127.0.0.0/8
   option                  redispatch
   retries                 3
   timeout http-request    10s
   timeout queue           1m
   timeout connect         10s
   timeout client          1m
   timeout server          1m
   timeout http-keep-alive 10s
   timeout check           10s
   maxconn                 3000
frontend main *:80
   acl url_dy       path_end       -i .php     #ACL规则,以.php结尾的URL将会被匹配
   use_backend dy          if url_dy       #匹配成功的将会调用“dy”后端服务器组
   default_backend            websrvs
listen stats
    modehttp
    bind172.16.9.84:7009
    statsenable
    statshide-version
    statsuri   /haproxyadmin?stats
    statsrealm HAProxy\ Statistics
    statsauth  admin:admin
    statsadmin if  TRUE
backend dy
   balance     roundrobin
   server      static172.16.9.83:8080 check
backend websrvs
   balance     roundrobin
   server  web1 172.16.9.81:8080check
   server  web2 172.16.9.83:8080check


7.3 后端服务器节点http页面内容

web-01节点的内容

[root@node-01 html]# cat index.htmlindex.php
<h1>Html Static Web-01</h1>
<h1>Real Server node-01</h1>


web-02节点的内容

[root@node-03 html]# cat index.htmlindex.php
<h1>Html Static Web-02</h1>
<h1>Real Server node-02</h1>


7.4 重新加载haproxy配置文件

service haproxy reload


7.5 访问测试

使用curl命令访问测试,静态资源的访问,将会出现轮询的效果:

[root@node-04 ~]# curl http://172.16.9.84/index.html
<h1>Html Static Web-01</h1>
[root@node-04 ~]# curlhttp://172.16.9.84/index.html
<h1>Html Static Web-02</h1>


使用curl命令访问测试,动态资源的访问,将会始终调度至同一台后端服务器的效果:

[root@node-04 ~]# curlhttp://172.16.9.84/index.php
<h1>Real Server node-02</h1>
[root@node-04 ~]# curl http://172.16.9.84/index.php
<h1>Real Server node-02</h1>


 

小结:

  haproxy的功能还远远不至上面列出的这些,更详细的内容请参考官方文档。

  haproxy的连接数是受套接字数量的限制,所以并发数量有限,在haproxy的前端可以加一个LVS,在LVS后一个haproxy的集群,通过LVS调度至不同的haproxy服务器上,以实现高并发的场景。


本文出自 “乌大宛” 博客,请务必保留此出处http://wuday.blog.51cto.com/2623944/1661745

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。