1 HAproxy介绍
1.1 Haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一,它支持双机热备、虚拟主机、基于TCP和HTTP应用代理等功能。其配置简单,并且拥有很好的对服务器节点的健康检查功能(至关于keepalived健康检查),当其代理的后端服务器出现故障时,Haproxy会自动的将该故障服务器摘除,当服务器的故障恢复后Haproxy还会自动将RS服务器上线
1.2 Haproxy特别适用与那些访问量很大。但又须要会话保持或七层应用的业务。Haproxy运行在普通的服务器硬件上,仅仅进行简单的优化就能够支持数以万计的并发链接。而且它的运行模式使得它能够很简单安全的整合到各类网站的架构中,同时使得应用服务器不会暴露到网络中
1.3 HAProxy 实现了一种事件驱动、单一进程模型,此模型支持很是大的并发链接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,不多能处理数千并发链接。事件驱动模型由于在有更好的资源和时间管理的用户端(User-Space) 实现全部这些任务,因此没有这些问题。此模型的弊端是,在多核系统上,这些程序一般扩展性较差。这就是为何他们必须进行优化以 使每一个CPU时间片(Cycle)作更多的工做
1.4 HAProxy 支持链接拒绝 : 由于维护一个链接的打开的开销是很低的,有时咱们很须要限制***蠕虫(attack bots),也就是说限制它们的链接打开从而限制它们的危害。 这个已经为一个陷于小型DDoS***的网站开发了并且已经拯救了不少站点,这个优势也是其它负载均衡器没有的
1.5 HAProxy 支持全透明代理(已具有硬件防火墙的典型特色): 能够用客户端IP地址或者任何其余地址来链接后端服务器. 这个特性仅在Linux 2.4/2.6内核打了cttproxy补丁后才可使用. 这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能
1.6 Haproxy软件引入了frontend,backend的功能,frontend(acl规则匹配)能够运维管理人员根据任意HTTP请求头作规则匹配,而后把请求定向到相关的backend(server pools等待前端把请求转过来的服务器组)。经过frontend和backup,咱们能够很容易的实现haproxy的7层代理功能,haproxy是一款不可多得的优秀代理服务软件
1.7 Haproxy支持两种主要代理模式:第一个是4层tcp代理(例如:可用于邮件服务内部协议通讯服务器、Mysql服务等)。第二个是7层代理(如HTTP代理)。在4层tcp代理模式下,Haproxy仅在客户端和服务器之间双向转发流量。可是在7层模式下Haproxy会分析应用层协议,而且能经过运行、拒绝、交换、增长、修改或者删除请求(request)或者回应(reponse)里指定内容来控制协议javascript
2 Haproxy解决方案拓扑图
2.1 Haproxy L4负载均衡应用架构拓扑
Haproxy软件的四层tcp代理应用很是优秀,配置很是简单方便,比LVS和Nginx要方便不少,由于不须要在RS端执行脚本便可实现应用代理。
说明:因为Haproxy采用的是NAT模式,数据包来去都会通过Haproxy,所以,在流量特别大的状况下,其性能不如LVS。
在通常的中小型公司,建议采用haproxy作负载均衡,而不要使用LVS或者Nginx。
所谓的四层就是ISO参考模型中的第四层。四层负载均衡也称为四层交换机,它主要是经过分析IP层及TCP/UDP层的流量实现的基于IP加端口的负载均衡。常见的基于四层的负载均衡器有LVS、F5等。
以常见的TCP应用为例,负载均衡器在接收到第一个来自客户端的SYN请求时,会经过设定的负载均衡算法选择一个最佳的后端服务器,同时将报文中目标IP地址修改成后端服务器IP,而后直接转发给该后端服务器,这样一个负载均衡请求就完成了。从这个过程来看,一个TCP链接是客户端和服务器直接创建的,而负载均衡器只不过完成了一个相似路由器的转发动做。在某些负载均衡策略中,为保证后端服务器返回的报文能够正确传递给负载均衡器,在转发报文的同时可能还会对报文原来的源地址进行修改。整个过程下图所示php
2.2 Haproxy L7负载均衡应用架构拓扑
Haproxy软件的最大优势在于其7层的根据URL请求头应用过滤的功能,通常用在LVS软件的下一层,或者像官方推荐的能够挂在硬件负载均衡NS、F5下使用
七层负载均衡器也称为七层交换机,位于OSI的最高层,即应用层,此时负载均衡器支持多种应用协议,常见的有HTTP、FTP、SMTP等。七层负载均衡器能够根据报文内容,再配合负载均衡算法来选择后端服务器,所以也称为“内容交换器”。好比,对于Web服务器的负载均衡,七层负载均衡器不但能够根据“IP+端口”的方式进行负载分流,还能够根据网站的URL、访问域名、浏览器类别、语言等决定负载均衡的策略。例如,有两台Web服务器分别对应中英文两个网站,两个域名分别是A、B,要实现访问A域名时进入中文网站,访问B域名时进入英文网站,这在四层负载均衡器中几乎是没法实现的,而七层负载均衡能够根据客户端访问域名的不一样选择对应的网页进行负载均衡处理。常见的七层负载均衡器有HAproxy、Nginx等。
这里仍以常见的TCP应用为例,因为负载均衡器要获取到报文的内容,所以只能先代替后端服务器和客户端创建链接,接着,才能收到客户端发送过来的报文内容,而后再根据该报文中特定字段加上负载均衡器中设置的负载均衡算法来决定最终选择的内部服务器。纵观整个过程,七层负载均衡器在这种状况下相似于一个代理服务器。整个过程以下图所示css
对比四层负载均衡和七层负载均衡运行的整个过程,能够看出,在七层负载均衡模式下,负载均衡器与客户端及后端的服务器会分别创建一次TCP链接,而在四层负载均衡模式下,仅创建一次TCP链接。由此可知,七层负载均衡对负载均衡设备的要求更高,而七层负载均衡的处理能力也必然低于四层模式的负载均衡html
3 安装haproxy
3.1 yum -y install haproxy
rpm -qi haproxy (版本为1.5.4)
rpm -ql haproxy
/etc/haproxy
/etc/haproxy/haproxy.cfg(haproxy的配置文件)
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
3.2 详细的配置文件
haproxy配置文件分为两部分组成:全局设定和代理的设定,共分为五段:obal,default,frontend,backend,listen
3.2.1 配置文件格式
haproxy的配置处理3类主要参数来源:
最优先处理的命令行参数
"global"配置段,用于设定全局配置参数
proxy相关配置段,如“default”、“listen”、“frontend”和“backend”
3.2.2 时间格式
一些包含了值的参数表示时间,如超长时间。这些值通常以毫秒为单位,但也可使用其余的时间单位后缀
us: 微秒(microseconds),即1/1000000秒;
ms: 毫秒(milliseconds),即1/1000秒;
s: 秒(seconds);
m: 分钟(minutes);
h:小时(hours);
d: 天(days);
3.2.3 全局的配置
进程管理及安全相关的参数前端
性能调整相关的参数
– maxconn <number>:设定每一个haproxy进程所接受的最大并发链接数,其等同于命令行选项“-n”;“ulimit -n”自动计算的结果正是参照此参数设定的;
– maxpipes <number>:haproxy使用pipe完成基于内核的tcp报文重组,此选项则用于设定每进程所容许使用的最大pipe个数;每一个pipe会打开两个文件描述符,所以,“ulimit -n”自动计算时会根据须要调大此值;默认为maxconn/4,其一般会显得过大;
– noepoll:在Linux系统上禁用epoll机制;
– nokqueue:在BSE系统上禁用kqueue机制;
– nopoll:禁用poll机制;
– nosepoll:在Linux禁用启发式epoll机制;
– nosplice:禁止在Linux套接字上使用内核tcp重组,这会致使更多的recv/send系统调用;不过,在Linux 2.6.25-28系列的内核上,tcp重组功能有bug存在;
– spread-checks <0..50, in percent>:在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众服务器进行健康情况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增长或减少必定的随机时长;
– tune.bufsize <number>:设定buffer的大小,一样的内存条件小,较小的值可让haproxy有能力接受更多的并发链接,较大的值可让某些应用程序使用较大的cookie信息;默认为16384,其能够在编译时修改,不过强烈建议使用默认值;
– tune.chksize <number>:设定检查缓冲区的大小,单位为字节;更大的值有助于在较大的页面中完成基于字符串或模式的文本查找,但也会占用更多的系统资源;不建议修改;
– tune.maxaccept <number>:设定haproxy进程内核调度运行时一次性能够接受的链接的个数,较大的值能够带来较大的吞吐率,默认在单进程模式下为100,多进程模式下为8,设定为-1能够禁止此限制;通常不建议修改;
– tune.maxpollevents <number>:设定一次系统调用能够处理的事件最大数,默认值取决于OS;其值小于200时可节约带宽,但会略微增大网络延迟,而大于200时会下降延迟,但会稍稍增长网络带宽的占用量;
– tune.maxrewrite <number>:设定为首部重写或追加而预留的缓冲空间,建议使用1024左右的大小;在须要使用更大的空间时,haproxy会自动增长其值;
– tune.rcvbuf.client <number>:
– tune.rcvbuf.server <number>:设定内核套接字中服务端或客户端接收缓冲的大小,单位为字节;强烈推荐使用默认值;
– tune.sndbuf.client:
– tune.sndbuf.server:java
Debug相关的参数node
超时时长
timeout http request :在客户端创建链接但不请求数据时,关闭客户端链接
timeout queue :等待最大时长
timeout connect: 定义haproxy将客户端请求转发至后端服务器所等待的超时时长
timeout client:客户端非活动状态的超时时长
timeout server:客户端与服务器端创建链接后,等待服务器端的超时时长,
timeout http-keep-alive :定义保持链接的超时时长
timeout check:健康状态监测时的超时时间,太短会误判,过长资源消耗
maxconn :每一个server最大的链接数mysql
http-server-close : 在使用长链接时,为了不客户端超时没有关闭长链接,此功能可使服务器端关闭长链接
redispatch: 在使用基于cookie定向时,一旦后端某一server宕机时,会将会话从新定向至某一上游服务器,必须使用 的选项web
实现访问控制
http-request:7层过滤
tcp-request content:tcp层过滤,四层过滤
3.2.4 代理
代理相关的配置能够以下配置段中正则表达式
The default
values are the following ones :
cookie <value>:为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实现持久链接的功能;
maxconn <maxconn>:指定此服务器接受的最大并发链接数;若是发往此服务器的链接数目高于此处指定的值,其将被放置于请求队列,以等待其它链接被释放;
haproxy 有n个进程,每一个支持m个链接,后端有x个服务器,每一个最大支持y个链接,则 nm <= xy,若是后端服务器支持排队,则nm <= x(y+z),z为每一个服务器的排队队列
maxqueue <maxqueue>:设定请求队列的最大长度;
observe <mode>:经过观察服务器的通讯情况来断定其健康状态,默认为禁用,其支持的类型有“layer4”和“layer7”,“layer7”仅能用于http代理场景;
redir <prefix>:启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应;须要注意的是,在prefix后面不能使用/,且不能使用相对地址,以避免形成循环;例如:
server srv1 172.16.100.6:80 redir http://imageserver.feiyu.com check
weight <weight>:权重,默认为1,最大值为256,0表示不参与负载均衡(不被调度);
检查方法:
option httpchk
option httpchk
option httpchk
option httpchk :不能用于frontend段,例如:
backend https_relay
mode tcp
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www.feiyu.com
server apache1 192.168.1.1:443 check port 80
使用案例:
server first 172.16.100.7:1080 cookie first check inter 1000
server second 172.16.100.8:1080 cookie second check inter 1000
4.9 capture request header
capture request header <name> len <length>
捕获并记录指定的请求首部最近一次出现时的第一个值,仅能用于“frontend”和“listen”区段。捕获的首部值使用花括号{}括起来后添加进日志中。若是须要捕获多个首部值,它们将以指定的次序出如今日志文件中,并以竖线“|”做为分隔符。不存在的首部记录为空字符串,最常须要捕获的首部包括在虚拟主机环境中使用的“Host”、上传请求首部中的“Content-length”、快速区别真实用户和网络机器人的“User-agent”,以及代理环境中记录真实请求来源的“X-Forward-For”。
<name>:要捕获的首部的名称,此名称不区分字符大小写,但建议与它们出如今首部中的格式相同,好比大写首字母。须要注意的是,记录在日志中的是首部对应的值,而非首部名称。
<length>:指定记录首部值时所记录的精确长度,超出的部分将会被忽略。
能够捕获的请求首部的个数没有限制,但每一个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义
4.10 capture request header
capture response header <name> len <length>
捕获并记录响应首部,其格式和要点同请求首部
4.11 stats enable
启用基于程序编译时默认设置的统计报告,不能用于“frontend”区段。只要没有另外的其它设定,它们就会使用以下的配置:
5 ACL
haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来作出转发决策,这大大加强了其配置弹性。其配置法则一般分为两步,首先去定义ACL,即定义一个测试条件,然后在条件获得知足时执行某特定的动做,如阻止请求或转发至某特定的后端。定义ACL的语法格式以下。
acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(链接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl能够重名,这能够把多个测试条件定义为一个共同的acl;
<criterion>:测试标准,即对什么信息发起测试;测试方式能够由[flags]指定的标志进行调整;而有些测试标准也能够须要为其在以前指定一个操做符[operator];
[flags]:目前haproxy的acl支持的标志位有3个:
-i:不区分中模式字符的大小写;
-f:从指定的文件中加载模式;
--:标志符的强制结束标记,在模式中的字符串像标记符时使用;
<value>:acl测试条件支持的值有如下四类:
整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(若是出现相似小数的标识,其为一般为版本测试),且支持使用的操做符有5个,分别为eq、ge、gt、le和lt;
字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;若是在模式首部出现了-i,能够在其以前使用“–”标志位;
正则表达式:其机制类同字符串匹配;
IP地址及网络地址;
同一个acl中能够指定多个测试条件,这些测试条件须要由逻辑操做符指定其关系。条件间的组合测试关系有三种:“与”(默认即为与操做)、“或”(使用“||”操做符)以及“非”(使用“!”操做符)
5.1 经常使用的测试标准(criteria)
5.1.1 be_sess_rate
be_sess_rate(backend)<integer>
用于测试指定的backend上会话建立的速率(即每秒建立的会话数)是否知足指定的条件;经常使用于在指定backend上的会话速率太高时将用户请求转发至另外的backend,或用于阻止***行为。例如:
backend dynamic
mode http
acl being_scanned be_sess_rate gt 50
redirect location /error_pages/denied.html if being_scanned
5.1.2 fe_sess_rate
fe_sess_rate(frontend)<integer>
用于测试指定的frontend(或当前frontend)上的会话建立速率是否知足指定的条件;经常使用于为frontend指定一个合理的会话建立速率的上限以防止服务被滥用。例以下面的例子限定入站邮件速率不能大于50封/秒,全部在此指定范围以外的请求都将被延时50毫秒
frontend mail
bind :25
mode tcp
maxconn 500
acl too_fast fe_sess_rate ge 50
tcp-request inspect-delay 50ms
tcp-request content accept if ! too_fast
tcp-request content accept if WAIT_END
5.1.3 hdr<string>
hdr(header)<string>
用于测试请求报文中的全部首部或指定首部是否知足指定的条件;指定首部时,其名称不区分大小写,且在括号“()”中不能有任何多余的空白字符。测试服务器端的响应报文时可使用shdr()。例以下面的例子用于测试首部Connection的值是否为close
hdr(connection) -i close
5.1.4 method <string>
method<string>
测试HTTP请求报文中使用的方法
5.1.5 path_beg <string>
用于测试请求的URL是否以指定的模式开头。下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets头
acl url_static path_beg -i /static /images /javascript /stylesheets
5.1.6 path_end <string>
用于测试请求的URL是否以<string>指定的模式结尾。例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾
acl url_static path_end -i .jpg .gif .png .css .js
5.1.7 hdr_beg <string>
用于测试请求报文的指定首部的结尾部分是否符合<string>指定的模式
6 配置案例
前端调度器IP:192.168.1.210
后端应用服务器IP: 192.168.1.111 和 192.168.1.112
定义独立日志文件
[root@node1 haproxy]# vim /etc/rsyslog.conf #为其添加日志功能
$ModLoad imudp
$UDPServerRun 514 ------>启动udp,启动端口后将做为服务器工做
$ModLoad imtcp
$InputTCPServerRun 514 ------>启动tcp监听端口
local2.* /var/log/haproxy.log
[root@node1 haproxy]# service rsyslog restar
[root@LB haproxy]# vim haproxy.cfg
log 127.0.0.1 local2 --------->在global端中添加此行
一个最简单的http服务的配置
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 except 127.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 webser #webser为名称
option forwardfor
bind :80
default_backend app
backend app
balance roundrobin #使拥roundrobin 算法
server app1 192.168.1.111:80 check
server app2 192.168.1.112:80 check
haproxy统计页面的输出机制
frontend webser
log 127.0.0.1 local3
option forwardfor
bind :80
default_backend app
backend app
cookie node insert nocache
balance roundrobin
server app1 192.168.1.111:80 check cookie node1 intval 2 rise 1 fall 2
server app2 192.168.1.112:80 check cookie node2 intval 2 rise 1 fall 2
server backup 127.0.0.1:8010 check backup
listen statistics
bind :8009 # 自定义监听端口
stats enable # 启用基于程序编译时默认设置的统计报告
stats auth admin:admin # 统计页面用户名和密码设置
stats uri /admin?stats # 自定义统计页面的URL,默认为/haproxy?stats
stats hide-version # 隐藏统计页面上HAProxy的版本信息
stats refresh 30s # 统计页面自动刷新时间
stats admin if TRUE #若是认证经过就作管理功能,能够管理后端的服务器
stats realm Hapadmin # 统计页面密码框上提示文本,默认为Haproxy\ Statistics
动静分离示例
frontend webservs
bind :80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html
acl url_php path_end -i .php
acl host_static hdr_beg(host) -i img. imgs. video. videos. ftp. image. download.
use_backend static if url_static or host_static
use_backend dynamic if url_php
default_backend dynamic
backend static
balance roundrobin
server node1 192.168.1.111:80 check maxconn 3000
backend dynamic
balance roundrobin
server node2 192.168.1.112:80 check maxconn 1000
http服务器配置完整示例
#---------------------------------------------------------------------
#---------------------------------------------------------------------
global
#
#
#
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode http
log global
option httplog
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
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 30000
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend http-in
bind *:80
mode http
log global
option httpclose
option logasap #不等待响应结束就记录日志,表示提早记录日志,通常日志会记录响应时长,此不记录响应时长
option dontlognull #不记录空信息
capture request header Host len 20 #记录请求首部的前20个字符
capture request header Referer len 60 #referer跳转引用,就是上一级
default_backend servers
frontend healthcheck
bind :1099 #定义外部检测机制
mode http
option httpclose
option forwardfor
default_backend servers
backend servers
balance roundrobin
server websrv1 192.168.1.111:80 check maxconn 2000
server websrv2 192.168.1.112:80 check maxconn 2000
负载均衡MySQL服务的配置示例
#---------------------------------------------------------------------
#---------------------------------------------------------------------
global
#
#
#
#log 127.0.0.1 local2chroot /var/lib/haproxypidfile /var/run/haproxy.pidmaxconn 4000user haproxygroup haproxydaemondefaultsmode tcplog globaloption httplogoption dontlognullretries 3timeout http-request 10stimeout queue 1mtimeout connect 10stimeout client 1mtimeout server 1mtimeout http-keep-alive 10stimeout check 10smaxconn 600listen statsmode httpbind 0.0.0.0:1080stats enablestats hide-versionstats uri /haproxyadmin?statsstats realm Haproxy\ Statisticsstats auth admin:adminstats admin if TRUEfrontend mysqlbind *:3306mode tcplog globaldefault_backend mysqlserversbackend mysqlserversbalance leastconnserver dbsrv1 192.168.1.111:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300server dbsrv2 192.168.1.112:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300