HAProxy介绍和应用
HAProxy简介
HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。
包括 GitHub、Bitbucket、Stack Overflow、Reddit、Tumblr、Twitter和 Tuenti在内的知名网站,及亚马逊网络服务系统都使用了HAProxy。
HAProxy是法国人Willy Tarreau开发的一个开源软件,是一款应对客户端10000以上的同时连接的高性能的TCP和 HTTP负载均衡器。其功能是用来提供基于cookie的持久性, 基于内容的交换,过载保护的高级流量管制,自动故障切换 ,以正则表达式为基础的标题控制运行时间,基于Web的报表,高级日志记录以帮助排除故障的应用或网络及其他功能。
HAProxy基础概念
代理的作用
- 正向代理,反向代理
- 代理服务器,可以提供缓存功能加速客户端访问,同时可以对缓存数据进行有效性检查
- 内容路由:根据流量以及内容类型将请求转发至特定的服务器
- 转码器:支持压缩功能,将数据以压缩形式发送给客户端
缓存的作用
- 减少访冗余内容传输
- 节省带宽,缓解网络瓶颈
- 降低了对原始服务器的请求压力
- 降低了传输延迟
负载均衡集群
四层代理:lvs, nginx(stream),HAProxy(mode tcp)
通过分析IP层及TCP/UDP层的流量实现的基于“IP+端口”的负载均衡。七层代理:http: nginx(http, ngx_http_upstream_module), HAProxy(mode http), httpd, ats, perlbal, pound…
可以根据内容,再配合负载均衡算法来选择后端服务器,不但可以根据 “ip+端口”方式进行负载分流,还可以根据网站的URL,访问域名,浏览 器类别,语言等决定负载均衡的策略。
七层负载均衡模式下,负载均衡与客户端及后端的服务器会分别建立一次 TCP连接,而在四层负载均衡模式下(DR),仅建立一次TCP连接;七层负载均衡对负载均衡设备的要求更高,处理能力也低于四层负载均衡。
HAProxy与lvs的负载均衡很大一点不同的是,lvs仅仅是基于内核的简单调度,而HAProxy则是当请求到达反向代理端时,代理端帮前端去请求相应内容
HAProxy功能
- HAProxy是TCP/HTTP反向代理服务器,尤其适合于高可用性环境
- 可以针对HTTP请求添加cookie,进行路由后端服务器
- 可平衡负载至后端服务器,并支持持久连接
- 支持基于cookie进行调度
- 支持所有主服务器故障切换至备用服务器
- 支持专用端口实现监控服务
- 支持不影响现有连接情况下停止接受新连接请求
- 可以在双向添加,修改或删除HTTP报文首部
- 支持基于pattern实现连接请求的访问控制
- 通过特定的URI为授权用户提供详细的状态信息
- 支持http反向代理
- 支持动态程序的反向代理
- 支持基于数据库的反向代理
版本:1.4 1.5 1.6 1.7 1.8
HAProxy应用
HAProxy进行安全加固
用于测试指定的backend上会话创建的速率(即每秒创建的会话数)是否满足指定的条件;常用于在指定 backend上的会话速率过高时将用户请求转发至另外的backend,或用于阻止攻击行为。例如
backend dynamic
mode http
acl being_scanned be_sess_rate gt 100
redirect location /denied.html if being_scanned
通过ACL指定可访问的用户
阻断来自非指定IP的访问80端口的请求
acl myhost src 172.16.100.1
acl myport dst_port 80
tcp-request connection reject if !myhost myport
还可以用block
block if ! myhost myport
根据用户访问内容实现动静分离
frontend http-in
bind *:80
mode http
log global
option httpclose
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .jpeg .gif .png .css .js
use_backend static_servers if url_static
default_backend dynamic_servers
backend static_servers
balance roundrobin
server imgsrv1 172.18.64.7:80 check maxconn 6000
server imgsrv2 172.18.64.107:80 check maxconn 6000
backend dynamic_servers
balance source
server websrv1 172.18.64.17:80 check maxconn 1000
server websrv2 172.18.64.106:80 check maxconn 1000
HAProxy实现浏览器控制
阻断火狐浏览器发送的请求
acl firefox hdr_reg(User-Agent) -i .*firefox.*
block if firefox
将IE用户请求分配到静态服务器
acl ie_useragent hdr_reg(User-Agent) -i .*ie.*
use_backend static_servers if ie_useragent
HAProxy实现真实日志记录
option forwardfor [ except ] [ header ] [ if-none ] 允许在发往服务器的请求首部中插入“X-Forwarded-For”首部。
HAProxy工作于反向代理模式,其发往服务器的请求中的客户端IP均为HAProxy主机的地址而非真正客户端的地址,这会使得服务器端的日志信息记录不了真正的请求来源,“X-Forwarded-For”首部则可用于解决此问题。HAProxy可以 向每个发往服务器的请求上添加此首部,并以客户端IP为其value。 需要注意的是,HAProxy工作于隧道模式,其仅检查每一个连接的第一个请求,因此,仅第一个请求报文被附加此首部。 下面是一个例子。
frontend www
mode http
option forwardfor except 127.0.0.1
HAProxy实现会话保持
源地址hash(用户IP识别)Haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx的IP hash 指令)。
缺点:当后端一台服务器挂了以后会造成部分session丢失backend SOURCE_srv
mode http
balance source
server app-node1 10.31.1.179:80 check port 80 inter 3000 rise 3 fall 3
server app-node2 10.31.1.191:80 check port 80 inter 3000 rise 3 fall 3
server app-node3 10.31.0.35:80 check port 80 inter 3000 rise 3 fall 3cookie 识别 HAProxy 将WEB服务端返回给客户端的cookie中插入HAProxy中特定的字符串(或添加前缀)在后端的服务器COOKIE ID。
backend COOKIE_srv
mode http
cookie SERVERID insert indirect nocache
server app-node1 10.31.1.179:80 check port 80 cookie a inter 3000 rise 3 fall 3
server app-node2 10.31.1.191:80 check port 80 cookie b inter 3000 rise 3 fall 3
server app-node3 10.31.0.251:80 check port 80 cookie c inter 3000 rise 3 fall 3
在LB1上配置好HAProxy后,LB1将接受用户的所有请求。如果一个用户请求不包含任何cookie,那这个请求将被HAProxy转发到一台可用的WEB服务器。可能是webA,webB,webC。然后HAProxy将把处理这个请求的WEB服务器的cookie值插入到请求响应中。如SERVERID=A。当这个客户端再次访问 并在HTTP请求头中带有SERVERID=A,HAProxy将会把它的请求直接转发给webA处理。在请求到达 webA之前,cookie将被移除,webA将不会看到这个cookie。如果webA不可用,对应的请求将被转发到其他可用的WEB服务器,相应的cookie值也将被重新设置。
HAProxy性能优化参数
option redispatch:当server对应的服务器挂掉后,强制定向到其他健康的服务器
option dontlognull :保证HAProxy不记录上级负载均衡发送过来 的用于检测状态没有数据的心跳包
retries 3 : 3次连接失败就认为服务器不可用,主要通过后面的check检查
maxconn 30000 : 代理时所能接受的最大并发连接数, 应该要比后端主机的并发总和要小