haproxy详细介绍
haproxy详细介绍
异类深呼吸 发表于3年前
haproxy详细介绍
  • 发表于 3年前
  • 阅读 394
  • 收藏 2
  • 点赞 0
  • 评论 0

腾讯云实验室 1小时搭建人工智能应用,让技术更容易入门 免费体验 >>>   

摘要: haproxy配置和他的原理相比起来,了解原理和一些特性真心有帮助,所以网络上找了一部分内容,加上自己的一些总结

1、haproxy

官方地址:http://www.haproxy.org/

这部分介绍内容摘抄自网络自行整理

  • 免费开源,稳定性也是非常好,Haproxy稳定性可以与硬件级的F5相媲美;

  • 是一款提供高可用性、负载均衡以及基于TCP(四层)和HTTP(七层)应用的代理软件,HAProxy是完全免费的、借助HAProxy可以快速并且可靠的提供基于TCP和HTTP应用的代理解决方案。

  • 特别适用于那些负载特大的web站点, 这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上

  • 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。

  • 多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。

  • 事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

  • 实现了O(1)的弹性二叉树数据结构来支持更大的并发的情况下实现稳定的数据结构

  • 支持连接拒绝 : 因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害。 这个已经为一个陷于小型DDoS攻击的网站开发了而且已经拯救了很多站点,这个优点也是其它负载均衡器没有的。

  • 支持全透明代理(已具备硬件防火墙的典型特点): 可以用客户端IP地址或者任何其他地址来连接后端服务器. 这个特性仅在Linux 2.4/2.6内核打了cttproxy补丁后才可以使用. 这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。

  • 基于四层的TCP查询,HAProxy现多于线上的Mysql集群环境,我们常用于它作为MySQL(读)负载均衡;

  • 自带强大的监控服务器状态的页面;

  • 支持虚拟主机

1、功能

  • 客户端侧的长连接(client-side keep-alive)

  • TCP加速(TCP speedups)

  • 响应池(response buffering)

  • RDP协议

  • 基于源的粘性(source-based stickiness)

  • 更好的统计数据接口(a much better stats interfaces)

  • 更详细的健康状态检测机制(more verbose health checks)

  • 基于流量的健康评估机制(traffic-based health)

  • 支持HTTP认证

  • 服务器管理命令行接口(server management from the CLI)

  • 基于ACL的持久性(ACL-based persistence)

  • 日志分析器

2、性能

  • 若要获得最高性能,需要在Linux 2.6或打了epoll补丁的Linux 2.4上运行haproxy 1.2.5以上的版本。haproxy 1.1l默认使用的polling系统为select(),其处理的文件数达数千个时性能便会急剧下降。1.2和1.3版本默认的为poll(),在有些操作系统上可会也会有性能方面的问题,但在Solaris上表现相当不错。HAProxy 1.3在Linux 2.6及打了epoll补丁的Linux 2.4上默认使用epoll,在FreeBSD上使用kqueue,这两种机制在任何负载上都能提供恒定的性能表现。

  • 在较新版本的Linux 2.6(>=2.6.27.19)上,HAProxy还能够使用splice()系统调用在接口间无复制地转发任何数据,这甚至可以达到10Gbps的性能。

  • 基于以上事实,在x86或x86_64平台上,要获取最好性能的负载均衡器,建议按顺序考虑以下方案。

Linux 2.6.32及之后版本上运行HAProxy 1.4; 
打了epoll补丁的Linux 2.4上运行HAProxy 1.4;
FreeBSD上运行HAProxy 1.4;
Solaris 10上运行HAProxy 1.4;
  • HAProxy借助于OS上几种常见的技术来实现性能的最大化。

1、单进程、事件驱动模型显著降低了上下文切换的开销及内存占用。 
2、O(1)事件检查器(event checker)允许其在高并发连接中对任何连接的任何事件实现即时探测。
3、在任何可用的情况下,单缓冲(single buffering)机制能以不复制任何数据的方式完成读写操作,这会节约大量的CPU时钟周期及内存带宽;
4、借助于Linux 2.6 (>= 2.6.27.19)上的splice()系统调用,HAProxy可以实现零复制转发(Zero-copy forwarding),在Linux 3.5及以上的OS中还可以实现零复制启动(zero-starting);
5、MRU内存分配器在固定大小的内存池中可实现即时内存分配,这能够显著减少创建一个会话的时长;
6、树型存储:侧重于使用作者多年前开发的弹性二叉树,实现了以O(log(N))的低开销来保持计时器命令、保持运行队列命令及管理轮询及最少连接队列;
7、优化的HTTP首部分析:优化的首部分析功能避免了在HTTP首部分析过程中重读任何内存区域;
8、精心地降低了昂贵的系统调用,大部分工作都在用户空间完成,如时间读取、缓冲聚合及文件描述符的启用和禁用等;
  • 所有的这些细微之处的优化实现了在中等规模负载之上依然有着相当低的CPU负载,甚至于在非常高的负载场景中,5%的用户空间占用率和95%的系统空间占用率也是非常普遍的现象,这意味着HAProxy进程消耗比系统空间消耗低20倍以上。因此,对OS进行性能调优是非常重要的。即使用户空间的占用率提高一倍,其CPU占用率也仅为10%,这也解释了为何7层处理对性能影响有限这一现象。由此,在高端系统上HAProxy的7层性能可轻易超过硬件负载均衡设备。

  • 在生产环境中,在7层处理上使用HAProxy作为昂贵的高端硬件负载均衡设备故障故障时的紧急解决方案也时长可见。硬件负载均衡设备在“报文”级别处理请求,这在支持跨报文请求(request across multiple packets)有着较高的难度,并且它们不缓冲任何数据,因此有着较长的响应时间。对应地,软件负载均衡设备使用TCP缓冲,可建立极长的请求,且有着较大的响应时间。

3、部署

0、打开IP转发 
sed -i 's/\(net.ipv4.ip_forward =\).*/\1 1/' /etc/sysctl.conf | grep net.ipv4.ip_forward sysctl -p

1、最新版本已经更新到1.6的开发版,1.5的稳定版,不过epel里提供的仍旧是1.4.24,不过足够线上使用了
yum install haproxy -y

2、备份配置文件
cd /etc/haproxy/
cp haproxy.cfg haproxy.cfg.bak

3、打开用户打开进程和文件数
ulimit -u 65535
ulimit -n 65535

4、开启远程接受日志的功能,默认haproxy是远程写日志操作,所以需要打开远程接受日志
vim /etc/rsyslog.conf
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
# 让haproxy日志单独记录文件,不记录message日志
*.info;mail.none;authpriv.none;cron.none;local2.none /var/log/messages

# Save boot messages also to boot.log
# 单独指定local2的日志写入自定义的haproxy.log中
local2.* /var/log/haproxy.log

# 重启rsyslog即可
service rsyslog restart

4、配置:

全局配置:定义haproxy进程的工作特性,以及全局特性 
代理配置:
defaults:用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定
frontend:用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接
user-backend:
default-backend
backend:用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器
listen:通过关联“前端”和“后端”定义了一个完整的代理,通常只对TCP流量有用

4.1、为两台backend web作负载均衡

frontend webserver *:80 
# bind *:80
default_backend appservers

backend appservers
server node131 172.16.1.20:80 check
server node132 172.16.1.10:80 check

当backend中server大于1台的时候,默认开启了rr算法作负载均衡
上述的例子也可以写成,但是一般不建议这样,这样增加了backend和fronted的耦合度 
listen webserver bind *:80
server node131 172.16.1.20:80 check
server node132 172.16.1.10:80 check

4.2、隐藏stats页的版本号,并使用口令认证,修改默认的URL

sample-3使用自带的状态页,隐藏版本号,并进行简单用户验证,并进行基于页面进行管理,这部分可以定义在backend中,也可自定义在listen中 
listen stats
bind *:1999 #自定义一个stats页端口
stats enable #开启状态页
stats hide-version #隐藏版本号
stats realm HAProxy\ Stats #弹出提示信息
stats auth admin:admin #口令/密码
stats admin if TRUE #只有验证通过才开启管理功能
stats uri /test #修改默认状态页url

之后访问haproxy的http://IP/haproxy?stats即可

4.3、备份节点的backend

sample-4:利用backup作出维护测试页更新页,只有backend中的server全部不可用的时候backup才会生效 
listen webserver
bind *:80
server node131 172.16.1.20:80 check
server node132 172.16.1.10:80 check
server backup 127.0.0.1:8009 backup

4.4、转发请求

sample-5:转发,必须是外部可访问的请求,只转发GET和header请求 
backend webservers
balance roundrobin
# hash-type consistent
server static01 172.16.1.10:80 check redir http://www.baidu.com
server static02 172.16.1.20:80 check
server backup 127.0.0.1:8009 backup

5、常见调度方法

1、roundrobin:(默认的haproxy使用的调度方法)

- 权重在服务器运行时配置 
- 支持慢速启动
- 每组backend最多只能支持4095个server

2、static-rr:

- 必须在haproxy启动时配置生效 
- 不支持慢速启动
- 每组backend后端server无限制

3、leastconn:

- 不适合web场景 
- 适合场景DB的负载均衡中

4、source:

类似于nginx的ip-hash,对每一个会话生产进行hash,所以可以对始终来源同一个ip的会话定位到同一个server上

- 取决于hash-type来决定是否是静态还是动态 
map-base:这时候source调度方法就是静态的
consistent:这时候source调度方法就是动态的
sample:实现会话保持,通过使用动态的source调度方法,实现来源同一个IP始终连接到同一个后端server上 
backend webservers
balance source
hash-type consistent
server node01 172.16.1.10:80 check
server node02 172.16.1.20:80 check

5、uri

根据url进行调度,对url进行hash,对请求的url进行负载均衡,适合一些backend为缓存服务器的负载均衡,只要会话是同一个url,则一直访问同一台服务器

- 取决于hash-type来决定是否是静态还是动态 
map-base:这时候source调度方法就是静态的
consistent:这时候source调度方法就是动态的
backend webservers 
balance uri
hash-type consistent
server node01 172.16.1.10:80 check
server node02 172.16.1.20:80 check

6、url param

指定request中的GET方法中的参数进行调度,根据同一个ID会话发往同一组backend,用于一些特殊场景中

- 取决于hash-type来决定是否是静态还是动态 
map-base:这时候source调度方法就是静态的
consistent:这时候source调度方法就是动态的

7、header

根据首部信息进行负载调度,包括request header和response header

6、option

defaults 
mode http #默认的haproxy对于长链接请求只会记录第一次请求,对于http来说如果想要记录更精确的请求则需要开启httplog,默认开启
log global #支持服务器端关闭,并且可以支持每个请求记录所有日志,支持长链接,多会话使用,建议开启
option httplog #在代理转发客户端请求到后端时候加个特殊首部,排除自己的请求(此时后端的请求的真实地址会变成haproxy的内网地址)
option dontlognull #不记录空信息
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m #和内部server连接队列超时
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000

7、ACL

7.1、针对源的acl

使用block返回码就是403.并针对这个403返回指定页面

frontend webserver
bind *:80
default_backend webservers
acl testacl src 192.168.122.0/24
block if testacl
errorloc 403 http://www.baidu.com/

7.2、对用户访问目标地址进行检查

如果是IP地址访问,重定向到一个地址

frontend webserver 
bind *:80
default_backend webservers
acl testacl src 192.168.122.0/24
acl dstaddr hdr(Host) 192.168.122.133
redirect location http://www.baidu.com/ if dstaddr

7.3、针对request的函数进行判断

实现用户的上传和下载的分离

frontend webserver 
bind *:80
acl read method GET
acl read method HEAD
acl write method PUT
acl write method POST

use_backend static if read
use_backend uploadser if write

backend static
...

backend uploadser
...

7.4、拒绝访问

针对单一文件的拒绝访问

frontend webserver 
bind *:80
default_backend webservers
acl testacl path /a.jsp
http-request deny if testacl

7.5、字符匹配和正则匹配

但是这里注意使用正则匹配会比使用字符匹配慢很多

acl url_static path_beg -i /static /images /js 
acl url_static path_end -i .jpg .jpeg .gif .png .css .js

use_backend static_servers if url_static
default_backend dynamic_servers

#使用path的开头和结尾部分进行匹配
acl url_static path_reg -i .jpg$ .gif$ .png$ .css$

7.6、动静态资源的分离访问

原理仍旧是上面字符匹配

所以根据上面的acl,实现动静态分离大致就为如下 
frontend webserver
bind 10.0.12.1:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js

use_backend static if url_static
default_backend appserver

backend static
balance roundrobin
server static 192.168.122.10:80 check
server static 192.168.122.20:80 check

backend appserver
balance roundrobin
server app1 192.168.122.30:8080 check
server app2 192.168.122.40:8080 check
共有 人打赏支持
粉丝 6
博文 46
码字总数 42368
×
异类深呼吸
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: