一、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。
[[email protected] 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
[[email protected] ~]# service haproxy start Starting haproxy: [ OK ]
4.4 检查监听端口
[[email protected] ~]# 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节点的配置内容
[[email protected] 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命令进行测试,将会出现轮询的效果
[[email protected] haproxy]# curlhttp://172.16.9.84 <h1>Real Server node-01</h1> [[email protected] 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的配置信息
[[email protected] 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节点的内容
[[email protected] html]# cat index.htmlindex.php <h1>Html Static Web-01</h1> <h1>Real Server node-01</h1>
web-02节点的内容
[[email protected] 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命令访问测试,静态资源的访问,将会出现轮询的效果:
[[email protected] ~]# curl http://172.16.9.84/index.html <h1>Html Static Web-01</h1> [[email protected] ~]# curlhttp://172.16.9.84/index.html <h1>Html Static Web-02</h1>
使用curl命令访问测试,动态资源的访问,将会始终调度至同一台后端服务器的效果:
[[email protected] ~]# curlhttp://172.16.9.84/index.php <h1>Real Server node-02</h1> [[email protected] ~]# curl http://172.16.9.84/index.php <h1>Real Server node-02</h1>
小结:
haproxy的功能还远远不至上面列出的这些,更详细的内容请参考官方文档。
haproxy的连接数是受套接字数量的限制,所以并发数量有限,在haproxy的前端可以加一个LVS,在LVS后一个haproxy的集群,通过LVS调度至不同的haproxy服务器上,以实现高并发的场景。