睿象云智能告警平台的分派策略
842
2022-10-14
Haproxy基础知识 -运维小结
开源软件负载均衡器
HAProxy负载均衡的特点1) 支持两种代理模式:TCP(四层)和HTTP(七层),支持虚拟主机; 2) 能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作 3) 支持url检测后端的服务器出问题的检测会有很好的帮助。 4) 更多负载均衡策略比如:动态加权轮循(Dynamic Round Robin),加权源地址哈希(Weighted Source Hash),加权URL哈希和加权参数哈希(Weighted Parameter Hash)已经实现 5) 单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度。 6) HAProxy可以对Mysql进行负载均衡,对后端的DB节点进行检测和负载均衡。 9) 支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(带权轮循)、source(原地址保持)、RI(请求URL)、rdp-cookie(根据cookie) 10) 不能做Web服务器即Cache。
这三大主流软件负载均衡器适用业务场景1) 网站建设初期,可以选用Nigix/HAproxy作为反向代理负载均衡(或者流量不大都可以不选用负载均衡),因为其配置简单,性能也能满足一般的业务场景。如果考虑到负载均衡器是有单点问题,可以采用Nginx+Keepalived/HAproxy+Keepalived避免负载均衡器自身的单点问题。 2) 网站并发达到一定程度之后,为了提高稳定性和转发效率,可以使用LVS、毕竟LVS比Nginx/HAproxy要更稳定,转发效率也更高。不过维护LVS对维护人员的要求也会更高,投入成本也更大。
需要注意的是Niginx与Haproxy比较: Niginx支持七层、用户量最大,稳定性比较可靠。Haproxy支持四层和七层,支持更多的负载均衡算法,支持session保存等。具体选型看使用场景,目前来说Haproxy由于弥补了一些Niginx的缺点致使其用户量也不断在提升。
衡量负载均衡器好坏的几个重要因素1) 会话率 :单位时间内的处理的请求数 2) 会话并发能力:并发处理能力 3) 数据率:处理数据能力 经过官方测试统计,haproxy 单位时间处理的最大请求数为20000个,可以同时维护40000-50000个并发连接,最大数据处理能力为10Gbps。综合上述,haproxy是性能优越的负载均衡、反向代理服务器。
Haproxy简介
HAProxy是法国人Willy Tarreau开发的一款可应对客户端10000以上的同时连接的高性能的TCP和HTTP负载均衡器。由于其丰富强大的功能在国内备受推崇,是目前主流的负载均衡器。Haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一,它支持双机热备、虚拟主机、基于TCP和HTTP应用代理等功能。其配置简单,而且拥有很好的对服务器节点的健康检查功能(相当于keepalived健康检查),当其代理的后端服务器出现故障时,Haproxy会自动的将该故障服务器摘除,当服务器的故障恢复后haproxy还会自动重新添加回服务器主机。
Haproxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space)实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么必须对其进行优化以使每个CPU时间片(Cycle)做更多的工作。
Haproxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。haproxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进当前架构中,同时可以保护web服务器不被暴露到网络上。
Haproxy软件引入了frontend,backend的功能,frontend(acl规则匹配)可以根据任意HTTP请求头做规则匹配,然后把请求定向到相关的backend(server pools等待前端把请求转过来的服务器组)。通过frontend和backend,可以很容易的实现Haproxy的7层负载均衡代理功能。
Haproxy是一种高效、可靠、免费的高可用及负载均衡解决方案,非常适合于高负载站点的七层数据请求。客户端通过Haproxy代理服务器获得站点页面,而代理服务器收到客户请求后根据负载均衡的规则将请求数据转发给后端真实服务器。同一客户端访问服务器,Haproxy保持回话的三种方案:1) Haproxy将客户端ip进行Hash计算并保存,由此确保相同IP访问时被转发到同一真实服务器上。2) Haproxy依靠真实服务器发送给客户端的cookie信息进行回话保持。3) Haproxy保存真实服务器的session及服务器标识,实现会话保持功能。
Haproxy工作原理
Haproxy提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。Haproxy特别适用于那些负载特别大的web站点,这些站点通常又需要会话保持或七层处理。Haproxy运行在时下的硬件上,完全可以支持数以万计的并发连接,并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上。
Haproxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space)实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以使每个CPU时间片(Cycle)做更多的工作。
Haproxy的优点1)免费开源,稳定性也是非常好。单Haproxy也跑得不错,稳定性可以与硬件级的F5相媲美。2)根据官方文档,Haproxy可以跑满10Gbps,这个数值作为软件级负载均衡器是相当惊人的。3)Haproxy支持连接拒绝:因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害。这个已经为一个陷于小型DDoS攻击的网站开发了而且已经拯救了很多站点,这个优点也是其它负载均衡器没有的。4)Haproxy支持全透明代理(已具备硬件防火墙的典型特点):可以用客户端IP地址或者任何其他地址来连接后端服务器。这个特性仅在Linux 2.4/2.6内核打了tcp proxy补丁后才可以使用。这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。5)Haproxy现在多用于线上的Mysql集群环境,常用于它作为MySQL(读)负载均衡。6)自带强大的监控服务器状态的页面,实际环境中我们结合Nagios进行邮件或短信报警。7)Haproxy支持虚拟主机,许多朋友说它不支持虚拟主机是错误的,但是通过测试可知,Haproxy是支持虚拟主机的。
Haproxy主要工作位置
Haproxy 相关术语
访问控制列表(ACL)在负载均衡当中,ACL用于测试某些状况,并根据测试结果执行某些操作(例如选定一套服务器或者屏蔽某条请求), 如下ACL示例
acl url_blog path_beg /blog
Backend所谓backend是指一组服务器,负责接收各转发请求。Backend在HAProxy配置中的backend部分进行定义。一般来讲,backend的定义主要包括:- 使用哪种负载均衡算法- 一套服务器与端口列表
一条backend能够容纳一套或者多套服务器——总体而言向backend中添加更多服务器将能够将负载扩散至更多服务器,从而增加潜在负载容量。这种方式也能够提升可靠性,从而应对部分后端服务器发生故障的情况。
下面来看一套双backend配置示例,分别为web-backend与blog-backend,其各自包含两套Web服务器,且监听端口80:
Frontend一条frontend负责定义请求如何被转发至backend。Frontend在HAProxy配置中的frontend部分进行定义。其定义由以下几部分组成:.一组IP地址与一个端口(例如10.1.1.7:80, *:443,等等).ACL.use_backend规则,其负责根据当前ACL条件定义使用哪个backend,而default_backend规则处理一切其它情况我们可以将同一frontend配置至多种不同网络流量类型
可以将同一frontend配置至多种不同网络流量类型!
下面了解负载均衡的基本类型。
无负载均衡简单的无负载均衡Web应用环境, 用户会直接接入Web服务器,即kevin.com且其中不存在负载均衡机制。如果单一Web服务器发生故障,用户将无法接入该服务器。另外,如果多位用户同时访问该服务器,且其无法处理该负载,则可能出现响应缓慢或者无法接入的情况。
frontend web_80 mode tcp bind :80 default_backend web-backendbackend web-backend mode tcp server 172.16.60.164 172.16.60.164:80 weight 1 check inter 1s rise 2 fall 2 server 172.16.60.165 172.16.60.165:80 weight 1 check inter 1s rise 2 fall 2
用户访问负载均衡器,后者将用户请求转发至后端服务器的web-backend组。被选定的后端服务器将直接响应用户请求。总体而言,web-backend中的全部服务器都应当拥有同样的内容, 否则用户可能会遭遇内容不一致问题。请注意后端两个Web服务器都接入同样的数据库服务器。
七层负载均衡另一种更为复杂的负载均衡方式,网络流量使用7层(即应用层)负载均衡。使用7层意味着负载均衡器能够根据用户的请求内容将请求转发至不同后端服务器。这种方式允许大家在同一域名及端口上运行多套Web应用服务器。下图为一套简单的7层负载均衡示例在本示例中,如果用户向kevin.com/blog发送请求,则会被转发至blog后端,其包含一组运行有同一blog应用的服务器。其它请求则会被转发至web-backend,其负责运行其它应用。本示例中的两套backend皆使用同样的数据库服务器。下面来看本示例中frontend配置片段
负载均衡算法负载均衡算法用于检测后端中的哪套服务器被负载均衡机制选定进行请求响应。HAProxy提供多种算法选项。除了负载均衡算法之外,我们还能够为服务器分配一个weight参数以指定该服务器被选定的频率。由于HAProxy提供多种负载均衡算法,因此我们下面只提及其中的一部分。来看几种常用算法:
roundrobinRound Robin会对服务器进行轮流选定,亦为HAProxy的默认算法。即客户端每访问一次, 请求就跳转打到后端不同的节点机器上.
leastconn选定连接数量最少的服务器——建议在周期较长的会话中使用这一算法。同一后端中的服务器亦会以轮循方式进行轮流选定。
source其根据源IP(即用户IP地址)进行服务器选定。通过这种方式,我们可以确定同一用户接入同一服务器。
粘性会话部分应用要求用户始终接入同一后端服务器,这一点需要利用粘性会话实现,其要求在backend中使用appsession参数。
运行状态检查HAProxy利用运行状态检查来检测后端服务器是否可用于处理请求。通过这种方式,我们不必以手动方式撤下不可用的后端服务器。默认运行状态检查会与目标服务器建立一条TCP连接,即检查后端服务器是否在监听所配置的IP地址与端口。
如果某套服务器未能通过运行状态检查,并因此无法响应请求,则其会在后端中被自动禁用——意味着流量将不再被转发到该服务器处,直到其重新恢复正常。如果后端中的全部服务器皆发生故障,则服务将不再可用,直到至少一套后端服务器重新恢复正常。
对于特定后端类型,例如特定状态下的数据库服务器,默认运行状态检查可能无法正确识别其正常与否。
其它解决方案如果大家认为HAProxy可能太过复杂,那么以下解决方案同样值得考虑:.Linux虚拟服务器(LVS) - 一套简单且快速的4层负载均衡器,多数Linux发行版都内置有这套方案。.Nginx - 一套快速且可靠的Web服务器,亦可用于代理及负载均衡。Nginx通常与HAProxy相结合以实现缓存及压缩功能。
Haproxy 使用细节梳理
以上简单介绍了Haproxy, 下面来整体梳理下Haproxy的使用:
Haproxy 程序环境
安装:yum install haproxy -y主程序: /usr/sbin/haproxy配置文件: /etc/haproxy/haproxy.cfg主配置文件主要结构:1) global 全局配置段 ; 2) proxies代理配置段
一. global 全局配置段
1.1) log:全局日志配置默认发往本机的日志服务器;1) 系统默认:log 127.0.0.1 local2 //表示发往远端可添加:log 远端IP local22) 修改本机日志配置文件
[root@localhost ~]# vim /etc/rsyslog.conf$ModLoad imudp #取消注释$UDPServerRun 514 #取消注释local2.* /var/log/haproxy.log #新增
3) 远端日志配置(配合前端log配置)
[root@localhost ~]# vim /etc/rsyslog.conflocal2.* /var/log/haproxy.log #新增
1.2) 性能调整(依据生产环境适当调整).maxconn
二. proxies 代理配置段结构1) defaults:为frontend, backend, listen提供默认配置;2) fronted:前端,指定接收客户端连接侦听套接字设置;3) backend:后端,指定将连接请求转发至后端服务器的相关设置;4) listen:同时拥有前端和后端,适用于一对一环境;
三. 简单haproxy代理案例实验拓扑:
3.1) 方法一配置 /etc/haproxy/haproxy.cfg, 将frontend段、backend段注释,新建如下配置
3.2) 方法二上面两段配置也可以配置在一段实现相同功能,配置如下
配置参数 bind:指定一个或多个前端侦听地址和端口语法: bind [
]:option选项说明
很少会有服务器不正确的忽略掉头,即使收到"Connection: close"也不关闭连接,否则就是不兼容HTTP 1.0浏览器标准。 如果发生这种情况,可以使用"option forceclose",在服务端响应后主动关闭请求连接。选项 "forceclose"还可以及早释放服务连接,而不必等到客户端的应答确认。
option forceclose 启用response后的主动关闭连接 (no option forceclose 表示禁止)
建议不将其设为默认值,因为大部分服务器会在发送完最后一个包之后更高效的关闭连接,并释放缓存,而且网络上的数据包也会略微降低整体的峰值性能。但是启用该选项,haproxy会略微少做一些工作。所以如果haproxy在整个架构中是个瓶颈,可以启用该操作,以节省CPU。
option forwardfor 如果服务器上的应用程序想记录发起请求的客户端的IP地址,需要在HAProxy上配置此选项,这样haproxy会把客户端的IP信息发送给服务器,在HTTP请求中添加"X-Forwarded-For"字段。
option originalto 如果服务器上的应用程序想记录发起请求的原目的IP地址,需要在HAProxy上配置此选项,这样haproxy会添加"X-Original-To"字段。
option dontlognull (即记录空连接)保证haproxy不记录上级负载均衡发送过来的用于检测状态没有数据的心跳包。
四. 代理配置段常见配置参数
4.1) Balance相关
balance:后端服务器组内的服务器调度算法语法: balance
hash类算法:需配合参数:hash-type
Haproxy中balance的算法总结,见下表
4.2) server:定义后端主机相关选项语法:server
[param*]:server后可加的参数weight
disabled:标记为不可用redir
基于cookie的session sticky的实现
4.3) 实现图形化配置页面stats enable 添加这条参数后会在web页面启用统计页;在frontend段添加stats enable ,重启haproxy。浏览器访问172.18.43.62/haproxy?stats即可。
listen admin bind 192.168.43.62:6666 stats enable stats uri /status stats realm "haproxy info" stats auth ha1:centos stats hide-version stats refresh 5s stats admin if TRUE
listen ssh bind :22022 balance leastconn mode tcp server sshsrv1 172.16.100.6:22 check server sshsrv2 172.16.100.7:22 check
4.5) forwardfor配置语法 :option forwardfor [ except
五. ACL灵活转发详解acl:访问控制列表(ACL)的使用提供了一个灵活的解决方案来执行内容交换,并且通常基于从请求中提取的内容、响应或任何环境状态进行决策,是haproxy的重要特色。
5.1) 语法acl
5.2) 匹配条件
(2)path : string提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分);
例:acl adminpath path_beg -i /admin acl imagefile path_end .jpg .png .bmp
(3)url : string提取请求中的URL。 一个典型的应用是具有预取能力的缓存,以及需要从数据库聚合多个信息并将它们保存在缓存中的网页门户入口 url : exact string match url_beg : prefix match url_dir : subdir match url_dom : domain match url_end : suffix match url_len : length match url_reg : regex match url_sub : substring match
(4)req.hdr([
(5)status : integer返回在响应报文中的状态码
5.3) acl作为条件时的逻辑关系 - 与:隐式(默认)使用 - 或:使用“or” 或 “||”表示 - 否定:使用“!“ 表示
同一个组名可定义多次示例: if invalid_src invalid_port #与关系 if invalid_src || invalid_port #或 if ! invalid_src #非
5.4) 预定义ACL(部分)
5.5) 配置block拒绝访问语法:block { if | unless }
例2(阻止curl访问)
acl bad_curl hdr_sub(User-Agent) -i curlblock if bad_curl
5.6) 指定backend组语法:use_backend
acl imagefile path_end .jpg .png .bmpacl appfile path_end .phpuse_backend websrvs1 if imagefileuse_backend websrvs2 if appfile
例2
例3
acl webhost hdr(host) web.kevin.comacl apphost hdr(host) app.kevin.comuse_backend websrvs if webhostuse_backend appsrvs if apphost
5.8) tcp4层连接控制语法:tcp-request connection {accept|reject} [{if | unless}
listen sshbind :22022balance leastconnacl invalid_src src 172.16.200.2tcp-request connection reject if invalid_srcmode tcpserver sshsrv1 172.16.100.6:22 checkserver sshsrv2 172.16.100.7:22 check backup
[root@localhost ~]# cd /etc/pki/tls/certs/[root@localhost ~]# make /etc/haproxy/haproxy.pem
测试
向后端传递用户请求
六. 基于ACL的动静分离示例
frontend web *:80 acl url_static path_beg -i /static /images /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm use_backend staticsrvs if url_static default_backend appsrvsbackend staticsrvs balance roundrobin server stcsrv1 172.16.100.6:80 checkbackend appsrvs balance roundrobin server app1 172.16.100.7:80 check server app1 172.16.100.7:8080 checklisten stats bind :9091 stats enable stats auth admin:admin stats admin if TRUE
分享一个小案例 如下的一个haproxy代理需求:
2.4) 默认跳转如果客户端访问的不是beijing.kevin.com与172.16.51.171,这两个地址的话,要把请求全部分发到172.16.51.178:8080上。
proxy.cfg配置内容如下:
补充下ACL规则的一些说明
ACL(Access Control List)访问控制列表,HAProxy中的ACL的匹配条件和控制条件有许多种,功能很强大,可以通过源地址、源端口、目标地址、目标端口、请求的资源类型、请求的主机等。
haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决策,这大大增强了其配置弹性。其配置法则通常分为两 步,首先去定义ACL,即定义一个测试条件,而后在条件得到满足时执行某特定的动作,如阻止请求或转发至某特定的后端。定义ACL的语法格式:acl
aclname:自定义acl的名称,必填项,只能是大小写、数字、'-'、'_'、'.'、':' , 也就是说这个是定义ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl;criterion:表示检查那些数据或内容,例如USERAGENT这个首部的值. 测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整;而有些测试标准也可以需要为其在
同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。条件间的组合测试关系有三种:“与”(默认即为与操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符);
Haproxy 会话保持 (三种方式)
Haproxy保持客户端session会话同步的三种方式梳理如下:
============第一种方式: 源地址hash(用户IP识别)==========haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令)。缺陷: 当后端一台服务器挂了以后会造成部分session丢失。
配置示例:
===========第二种方式: cookie 识别 ===========haproxy 将WEB服务端返回给客户端的cookie中插入haproxy中特定的字符串(或添加前缀)在后端的服务器cookie id。
配置指令例举: cookie SESSION_COOKIE insert indirect nocache用firebug可以观察到用户的请求头的cookie里 有类似" Cookie jsessionid=0bc588656ca05ecf7588c65f9be214f5;SESSION_COOKIE=app1"其中SESSION_COOKIE=app1就是haproxy添加的内容。
配置示例:
特别注意: rewrite | insert | prefix 这三个参数相互排斥,只能选一!rewrite: 表示cookie由服务器生成并且haproxy会在其值中注入该服务器的标识符;此关键字不能在HTTP隧道模式下工作。
insert: 表示如果客户端没有cookie信息且有权限访问服务器时,持久性cookie必须通过haproxy穿插在服务器的响应报文中。当服务器收到相同名称的cookie并且没有“preserve(保存)”选项时,将会移除之前已存的cookie信息。因此,insert可视作"rewrite"的升级版。cookie信息仅仅作为会话cookie且不会存到客户端的磁盘上。默认除非加了“indirect(间接)”选项,否则服务器端会看到客户端端发送的cookie信息。由于缓存的影响,最好加上“nocache”或“postonly”选项。
prefix: 表示不依赖专用的cookie做持久性,而是依赖现成的。用在某些特殊的场景,如客户端不支持一个以上的cookie和应用程序需求它。每当服务器建立一个名为
nocache: 当客户端和haproxy间存在缓存时,使用此选项和insert搭配最好,以便确保如果一个cookie需要被插入时,可被缓存的响应会被标记成不可缓存。这很重要,举个例子:如果所有的持久cookie被添加到一个可缓存的主页上,之后所有的客户将从外部高速缓存读取页面并将共享相同的持久性cookie,会造成服务器阻塞。
在LB服务器上配置好HAProxy后,LB服务器将接受用户的所有请求。如果一个用户请求不包含任何cookie,那这个请求将被HAProxy转发到一台可用的WEB服务器。可能是webA,webB,webC或webD。然后HAProxy将把处理这个请求的WEB服务器的cookie值插入到请求响应中。如SERVERID=A。当这个客户端再次访问并在HTTP请求头中带有SERVERID=A,HAProxy将会把它的请求直接转发给webA处理。在请求到达webA之前,cookie将被移除,webA将不会看到这个cookie。如果webA不可用,对应的请求将被转发到其他可用的WEB服务器,相应的cookie值也将被重新设置。
==============第三种方式: 基于session识别 ============haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。配置参数:appsession JSESSIONID len 64 timeout 5h request-learn
配置示例:
2) 由于一些原因,一些客户端不能识别多个cookie,并且后端应用已经设置了cookie,如果HAProxy再对响应插入cookie后,这些客户端可能不能识别cookie。这种情况下,可以使用cookie的prefix模式。
5) 在有些情况下,一些用户会将他们的浏览器的cookie功能关闭。这时候可能没法访问WEB服务器的内容。这种情况下,可以使用HAProxy的 source 负载均衡算法替代 roundroubin算法。source 算法可以确保来自同一个IP的所有请求都到达同一台WEB服务器,但是前提是,可用的服务器的数量保持不变。
6) 不要在一个小型网络和代理服务器后面使用source 算法,因为请求分发会不太公平,但是在大型内部网络或互联网上使用source算法,转发效率很好。对于那些具有动态IP地址的客户端,只要它们能够接收cookie,那么请求转发就不会受到影响,因为HAProxy对cookie的处理具有较高优先级。
===========================================================================================以上总结的指令和参数都是为了设置或定义ACL匹配条件的,即ACL仅仅只是将匹配条件进行分类归纳而不进行处理。若要将定义好的ACL规则做处理,需下面参数来设置:
1) 当符合指定的条件时使用特定的backend,
use_backend
2) 阻塞一个七层请求满足/不满足某一ACL匹配条件。格式如下
block { if | unless }
例如
acl invalid_src src 192.18.29.101 #acl匹配条件为源地址为192.18.29.101,acl名为invalid_srcblock if invalid_src #阻断满足名为invalid_src的acl匹配条件errorfile 403 /etc/fstab #并定义错误页
4) 配置四层的请求访问控制
tcp-request connection {accept|reject} [{if | unless}
例如:
listen sshbind :22022balance leastconnacl invalid_src src 172.16.200.2 #定义acl匹配规则tcp-request connection reject if invalid_src #在四层拒绝满足名为invalid_src的acl匹配规则mode tcpserver sshsrv1 172.16.100.6:22 checkserver sshsrv2 172.16.100.7:22 check
=======ACL示例======要注意到的是acl关键字可用在frontend、listen、backend中,不能用在default中。
例1:设置HAProxy状态页,只允许指定IP访问,设置如下
listen stats #定义名称 bind *:9099 #监听在9099端口 acl sta src 192.168.29.1 #匹配名为sta且源IP地址为192.168.29.1的ACL规则 block if ! sta #阻断不匹配sta规则的所有条件,!为非 stats enable #启用stats页 stats uri /myhaproxy?admin #自定义stats页面uri stats realm "Hello World" stats auth admin:admin #设置状态页登录账号和密码
提示错误401,只需输入账号密码即可访问,方法为
说明IP为29.104的主机可以访问,并无限制。添加限制后
再用IP为29.104的主机访问效果如下
此时错误为403,而29.1的主机是可以访问的(图太大了就省略了),说明ACL控制生效了。
例3: 七层规则匹配七层ACL规则匹配中,常用的参数是path,它用来做URL规则匹配,path包括以下参数:path : 精确匹配path_beg : 匹配字符串开头的所有内容path_dir : 子路径匹配path_dom : 域名匹配path_end : 匹配字符串结尾的所有内容path_len : 字符串长度匹配path_reg : 正则表达式匹配path_sub : 域名子串匹配
下面来举一个使用path的具体例子,选两台主机,安装Nginx并用Nginx虚拟为4台主机,两台用来处理图片请求,两台用来处理文本请求,利用HAProxy负载均衡的ACL控制机制实现,结构图如下:
1) 在192.168.29.102上添加监听8080端口的虚拟主机(安装的是Nginx),修改Nginx配置,在主配置中添加如下信息
server { listen 80 default_server; listen [::]:8080 default_server; server_name _; root /usr/share/nginx/html/test; #路径要修改,尽量不使用默认,尽量模拟为两台不同物理机的效果 # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
2) 在80端口的主机root目录下创建文件static.txt,内容为static 1;在8080端口主机root目录下创建文件static.txt,内容为static 2。重启Nginx服务,并确保能正常访问,如下图
3) 用同样的方法在192.168.29.103上创建分别监听在80和8080端口的虚拟主机,并在根目录下创建图片文件,确保能正常访问,如下图:
4) 在主机192.168.29.101上配置HAProxy
frontend myweb bind *:80 acl image path_end .png #匹配以.png结尾的path规则 acl txt path_end .txt #匹配以.txt结尾的path规则 use_backend imagesv if image #将规则image负载均衡到服务器组imagesv use_backend txtsv if txt #将规则txt负载均衡至服务器组txtsv default_backend app #默认组,无匹配时负载均衡至此backend imagesv balance roundrobin server image1 192.168.29.103:80 check server image2 192.168.29.103:8080 checkbackend txtsv balance roundrobin server txt1 192.168.29.102:80 check server txt2 192.168.29.102:8080 checkbackend app balance leastconn cookie server insert nocache server app1 192.168.29.102:80 check cookie svr1 server app2 192.168.29.103:80 check cookie svr2
配置完成后重启HAProxy,分别访问192.168.29.101/image.png和192.168.29.101/static.txt,并刷新,会发现内容会不停变化,如下图
这说明ACL规则培植成功,HAProxy会根据请求的结尾来判断负载均衡规则。简单总结: 上面举了3个很简单的HAProxy ACL访问控制的例子,虽然例子中的配置很粗糙,但也可以初步领略到HAProxy有着比较智能的负载均衡功能,在后面的博客中我会更深入的介绍HAProxy的细节配置与调优
================Haproxy ACL规则小例==============1) 按请求的主机头(名)负载[root@localhost ~]# cat haproxy.cfg
2) 其它ACL规则
use_backend 参数or 用于匹配多个acl 名称 default_backend 没有满足条件的时候使用默认的后端服务器
========HAProxy 七层层模型下强大的ACL规则配置示例========
use_backend test-proxy-srv-a if host_ause_backend test-proxy-srv-b if host_buse_backend test-proxy-srv-c if url_policydefault_backend test-proxy-srv-default
当然acl还有更多的用法,如下:acl url_static path_end .gif .png .jpg .css .jsacl host_www hdr_beg(host) -i wwwacl host_static hdr_beg(host) -i img. video. download. ftp.
use_backend static if host_static || host_www url_staticuse_backend www if host_wwwdefault_backend server_cache
第一个acl,通过path_end参数定义请求的url以.gif,.png,.jpg,.css,.js结尾时返回TRUE第二个acl,通过hdr_beg(host)参数定义如果客户端以www开头的域名发送请求时返回TRUE第三个acl,也是通过hdr_beg(host)参数定义以img.,video.,download.,ftp.开头域名发送请求返回TRUE第四行backend,定义了当请求需同时满足host_static与url_static时,或者满足host_www与url_static时请求将发往名为static 的backend第五行backend,定义了当请求满足host_www规则时,请求发往名为www的backend第六行backend,定义将用户请求默认调度到名为server-cache的backend
以上就是Haproxy的ACL常用控制用法,基本上可以满足日常负载需求。
========================设置haproxy负载均衡的最大并发连接数=======================
从三个方面来进行设置a) 查看内核[root@haproxy-test ~]# sysctl -a | grep filefs.file-nr = 1024 0 386459fs.file-max = 386459b) 查看应用层面的需求[root@haproxy-test ~]# vim /usr/local/haproxy/conf/haproxy.cfgglobal #全局参数设置 maxconn 65535 #设置最大连接数c) 更改系统层面[root@haproxy-test ~]# vim /etc/security/limits.conf #最后一行增加* - nofile 65535
===========================下面分析一个haproxy的负载均衡配置=============================
==========================整体总结下Haproxy的参数说明============================
一. Haproxy 配置说明haproxy的配置段有"global","defaults","listen","frontend"和"backend"等:global: 配置中的参数为进程级别的参数,且通常与其运行的操作系统有关defaults: 用于为所有其他配置段提供默认参数,这配置默认配置参数可由下一个"defaults"所重新设定forntend: 用于定义一系列监听的套接字,这些套接字可以接受客户端请求并与子建立连接backend: 用于定义一系列"后端"服务器,代理将会将对应客户端的请求转发至这些服务器listen: 用于定义通过关联"前段"和"后端"一个完整的代理,通常只对TCP流量有用
所有代理的名称只能使用大写字母、小写字母、数字、-(中线)、_(下划线)、.(点号)和:(冒号)。此外,ACL名称会区分大小写.
时间格式一些包含了值得参数表示时间,如超时时长。这些值一般都以毫秒为单位,但也可以使用其他的时间单位做后缀,如us(微妙,1/10000000秒),ms(毫秒,1/1000秒),s(秒),m(分钟),h(小时),d(天)
二. global 全局配置chroot: 修改haproxy的工作目录至指定的目录,并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是确保指定的目录为空目录且任何用户均不能有写权限;daemon: 让haproxy以守护进程的方式工作于后台,其等同于"-D"选项的功能,当然,也可以在命令行中以"-db"选项将其禁用;gid: 以指定的GID运行haproxy,建议使用专用于运行haproxy的GID,以避免因权限带来的风险;group: 同gid,不过这里为指定的组名;uid: 已指定的UID身份运行haproxy进程;user: 同uid,但这里使用的为用户名;log: 定义全局的syslog服务器,最多可以定义两个;nbproc: 指定启动的haproxy进程个数,只能用于守护进程模式的haproxy;默认为止启动一个进程,鉴于调试困难等多方面的原因,一般只在但进程仅能打开少数文件描述符的场中才使用多进程模式;pidfile: pid文件的存放位置;ulimit-n:设定每个进程所能够打开的最大文件描述符,默认情况下其会自动进行计算,因此不建议修改此选项;node: 定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时;description: 当前实例的描述信息;maxconn: 设定每个haproxy进程所接受的最大并发连接数,其等同于命令行选项"-n","ulimit-n"自动计算的结果正式参照从参数设定的;maxpipes: haproxy使用pipe完成基于内核的tcp报文重组,此选项用于设定每进程所允许使用的最大pipe个数,每个pipe会打开两个文件描述符,因此,"ulimit -n"自动计算的结果会根据需要调大此值,默认为maxcoon/4;noepoll: 在linux系统上禁用epoll机制;nokqueue: 在BSE系统上禁用kqueue机制;nopoll: 禁用poll机制;nosepoll: 在linux系统上禁用启发式epoll机制;nosplice: 禁止在linux套接字上使用tcp重组,这会导致更多的recv/send调用,不过,在linux2.6.25-28系列的内核上,tcp重组功能有bug存在;spread-checks<0..50,in percent>: 在haprorxy后端有着众多服务器的场景中,在紧缺是时间间隔后统一对中服务器进行健康状况检查可能会带来意外问题,此选项用于将检查的时间间隔长度上增加或减少一定的随机时长,为当前检查检测时间的%;tune.bufsize: 设定buffer的大小,同样的内存条件下,较小的值可以让haproxy有能力接受更多的并发连接,较大的值了可以让某些应用程序使用较大的cookie信息,默认为16384,其可以在编译时修改,不过强烈建议使用默认值;tune.chksize: 设定检查缓冲区的大小,单位为字节,更大的值有助于在较大的页面中完成基于字符串或模式的文本查找,但也会占用更多的系统资源,不建议修改;tune.maxaccept: 设定haproxy进程内核调度运行时一次性可以接受的连接的个数,较大的值可以带来较大的吞吐量,默认为单进程模式下为100,多进程模式下为8,设定为-1可以禁止此限制,一般不建议修改;tune.maxpollevents: 设定一次系统调用可以处理的事件最大数,默认值取决于OS,其至小于200时可介于带宽,但会略微增大网络延迟,但大于200时会降低延迟,但会稍稍增加网络带宽的占用;tune.maxrewrite: 设定在首部重写或追加而预留的缓存空间,建议使用1024左右的大小,在需要更大的空间时,haproxy会自动增加其值;tune.rcvbuf.client: 设定内核套接字中客户端接收缓存区的大小,单位为字节,强烈推荐使用默认值;tune.rcvbuf.server: 设定内核套接字中服务器接收缓存区的大小,单位为字节,强烈推荐使用默认值;tune.sndbuf.client: 设定内核套接字中客户端发送缓存区的大小,单位为字节,强烈推荐使用默认值;tune.sndbuf.server: 设定内核套接字中服务器端发送缓存区的大小,单位为字节,强烈推荐使用默认值;debug: 调试模式,输出启动信息到标准输出;quiet: 安装模式,启动时无输出;
三. defaults 默认配置defaults:用于为所有其他配置段提供默认参数,这配置默认配置参数可由下一个"defaults"所重新设定
1) balancebalance
roundrobin:基于权重进行轮询,在服务器的处理时间保持均匀分布时 ,这是最平衡、最公平的算法。此算法是动态的,这表示某权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多支持4128个连接; 即客户端请求每次都转发到不同的节点服务器上;
static-rr:基于权重进行轮询,与roundrobin类似,但是为静态方法,在运行时调整期后端权重不会生效,不过,其在后端服务器连接数上没有限制;
leastconn:新的连接强求笨哦派发至具有最少连接数目的后端服务器,在有这较长会话的场景中推荐使用此算法,如LDAP、SQL等。其并不太适合用于较短会话的应用层协议,如HTTP,此算法是动态的,可以在运行时调整其权重;
source:将请求的源地址进行hash运算,并有后端的服务器的权重总数相处后派发至某匹配的服务器,这可以使得同一个客户端IP的请求始终被派发至某特定的服务器,不过,当服务器权重总数发生变化时,如某服务器宕机或者添加新服务器,许多的请求可能会被派发至与此前请求不同的服务器,常用于负载均衡无cooki功能的基于TCP的协议,默认为动态,不过可以使用hash-type修改此特性;
uri:对URI的左半部分(“问号”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是派发至某匹配的服务器,除法服务器的权重总数发生了变化,此算法常用于代理缓存或反病毒代理以提高缓存的命中率,需要注意的是,此算法仅应用于HTTP后端服务器场景,其默认为静态算法,不过可以使用hash-type修改此特性;
url_param:通过
har(
2) bindbind [
]:tcp: 实例运行于纯tcp模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查,此为默认模式,通常用于SSL、SSH、SMTP等应用;
4) loglog globallog
5) maxconnmaxconn
如果为
6) default_backenddefault_backend
<:port>:指定将连接请求所发往此服务器时的目标端口,其为可选项,为设定是,将使用客户端请求时的同一相同端口;
weight
8) capture request headercapture request header
可以捕获的请求首部的个数没有限制,但每个捕获最多能记录64个字符,为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义;
9) capture response headercapture response header
10) stats enable启用基于程序编译时默认设置的统计报告,不能用于"frontend"区段,只要没有额外的其他设定,他们就会使用如下的配置: - stats uri : /haproxy?stats - stats realm : "HAProxy Statistics"- stats auth : no authentication- stats scope : no restriction尽管"stats enable"一条就能够启用统计报告,但还是建议设定其他所有的参数,以避免其依赖默认设定而带来非预期后果,下面是一个配置示例:
backend public_www server srv1 192.168.1.201:80 stats enable stats hide-version stats scope . stats uri /admin?stats stats realm Haproxy Statistics stats auth admin1:AdMiN123 stats auth admin2:AdMiN321
11) stats hide-version启用统计报告并隐藏HAProxy版本报告,不能用于"frontend"区域,默认情况下,统计页面会显示一些有用信息,包括HAProxy的版本号,然后,向所有人公开HAproxy的准确版本号是非常有危险的,因为他能够版主恶意用户快速定位版本的缺陷和漏洞,尽管"stats hide-version"一条就能够启用统计报告,但还是建议设定其他所有的参数,以避免其依赖默认设定而带来非预期后果.
12) stats realmstats realm
尽管"stats realm"一条就能够启用统计报告,但还是建议设定其他所有的参数,以避免其依赖默认设定而带来非预期.
13) stats scopestats scope {
尽管“stats scope”一条就能够启用统计报告,但还是建议设定其他所有的参数,以避免其依赖默认设定而带来非预期后果.
14) stats authstats auth
此语句将给予默认设定启用统计功能报告,并仅允许其定义的用户访问,其也可以定义多次以手段多个用户账号,可以结合"stats realm"参数在提示用户认证是给出一个领域说明信息,在使用非法用户访问统计功能时,其将会响应一个"401 Forbidden"页面,其认证方式为HTTP Basic认证,密码传输会以明文方式进行,因此,配置文件中也使用存储明文方式存储以说明其非保密信息故此不能想用与其他关键性账号的密码。
尽管"stats auth"一条就能够启用统计报告,但还是建议设定其他所有的参数,以避免其依赖默认设定而带来非预期后果.
15) stats admin atsts admin {if|unless}
目前来说,POST请求方法被限制于仅能使用缓冲区减去保留之外的空间,因此,服务器列表不能过长,否则,此请求将无法正常工作,因此,建议一次仅调整少数几个服务器.
clf:使用CLF格式来代替HAproxy默认的HTTP格式,通常在使用仅支持CLF格式的特定日志分析器时才需要使用此格式;
17) option logasap no option logasap启用或禁用提前将HTTP请求记入日志,不能用于“frontend”区段。
默认情况下,HTTP请求是在请求结束时进行记录以便能够将其整体输入时长和字节数记入日志,由此,传较大的对象时,其记入日志的市场可能会略有延迟,“option logasap”参数能够在服务器发送complete首部时及时记录日志,只不过,此时将不记录整体传输时长和字节数。此情形下,捕获“Content-Length”响应报文来记录的字节数是以一个较好的选择;
18) option forwardforoption forwardfor[ except
if-none: 仅在此首部不存在时才会将其添加至请求报文中;
HAproxy工作与反向代理模式,其发往服务器的请求中的客户端IP均为HAproxy主机的地址而非真正的客户端地址,这会使得服务器的日志记录不了真正的请求来源,"X-Forwarded-For"首部则可用于解决此问题,HAproxy可以向每个房网服务器的请求上添加此首部,并以客户端IP为其value;
19) errorfileerrorfile
: 指定对HTTP的那些状态码发回指定的页面,这里可用的状态码有200、400、403、408、500、502、503和504;
例如:
20) errorloc和errorloc302errorloc
: 指定对HTTP的那些状态码发回指定的页面,这里可用的状态码有200、400、403、408、500、502、503和504;
需要留意的是: 这两个关键字都会返回302状态码,浙江使得客户端使用同样的HTTP方法获取指定的URL。对于非GET方法获取指定的URL,对于非GET方法的场景(如POST)来说会产生问题,因为返回客户端的URL是不允许使用GET意外的其他方法的,如果的确有这种问题,可以使用errorloc303来返回303状态码给客户端;
21) errorloc303errorloc303
: 指定对HTTP的那些状态码发回指定的页面,这里可用的状态码有400、403、408、500、502、503和504;
需要注意的是,如果URI之神错误时禅师某特定状态码信息的话,有可能会导致循环定向.
发表评论
暂时没有评论,来抢沙发吧~