简介:HAProxy是一个免费的负载均衡软件,可以运行于大部分主流的Linux操作系统上。HAProxy提供了L4(TCP)和L7(HTTP)两种负载均衡能力,具备丰富的功能。HAProxy的社区非常活跃,版本更新快速,HAProxy具备媲美商用负载均衡器的性能和稳定性。因为HAProxy的上述优点,它当前不仅仅是免费负载均衡软件的首选,更几乎成为了唯一选择。
下面我将从3个方面来讲解从而帮助大家快速上手玩转haproxy
1.了解haproxy
1.1.环境配置
主机名 | IP | 服务 |
client | 172.25.254.10 | 客户端 |
haproxy | 172.25.254.100 192.168.132.100 | haproxy服务端 |
server1 | 192.168.132.101 | web服务器 httpd |
server2 | 192.168.132.102 | web服务器 nginx |
1.2 了解haproxy配置文件
yum install haproxy
cd /etc/haproxy
#查看我们的配置文件
vim haproxy.cfg
1.2.1 global 全局配置
除去上面我们还可以有以下几种
nbproc N | 开启的haproxy worker 进程数,默认为1个 |
nbthread 1 | 指定每个haproxy进程开启的线程数,默认一个进程一个线程 |
cpu-map A B | 绑定进程指定cpu,将A进程绑定到Bcpu上 |
log IP local2 info | 定义全局的syslog服务器但日志服务器需要开启udp协议最多定义2个 |
maxss|conn N | 每个进程ssl最大连接数,用于hproxy配置了证书的场景下 |
maxconnrate N | 每个进程每秒创建的最大连接数量 |
spread-checks N | 后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认值0 |
pidfile | 指定pid文件路径 |
1.2.2 默认配置
所有“listen”和“backend”部分(如果在它们的块中没有指定)都将使用的常见默认值
1.2.3 配置文件区
pstree -p | grep haproxy
#查看我们的进程前提是服务开启
2. 基础配置
2.1 简单来一段基础配置
check 开机检测异常情况
inter 健康状态检查间隔时间,默认为2s
fall 后端服务器从线上转为线下的连续监测失败次数,默认为3次
rise 后端服务器从线下恢复上线的连续监测有效次数,默认为2次
weight 权重,权重越大使用越多
backup 后端服务器标记为备份状态,只有主非备份主机死亡时启用
disable 将后端服务器标记为不可用
redirect prefix/redir 将请求临时302重定向到其他URL只适用于http服务
2.2 采用listen"合体"写法
2.3 来尝试一下标红功能
首先我们在server1上下载一个nginx并写入内容外加改端口号避免和我们的httpd冲突
vim /etc/nginx/nginx.conf
由于web1 和web2都被打上了不可用标签所以当我们访问就会被带到百度
这个时候我们就会访问到我们101上的8080端口
3 算法
很多时候我们要处理的情况很复杂单靠上面的配置我们很难完成我们想要的效果,于是乎就出现了各种各样的算法
3.1 静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
3.1.1 static-rr 基于权重的轮询调度
不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)
不支持端服务器慢启动
其后端主机数量没有限制,相当于LVS中的 wrr
3.1.2 first
根据服务器在列表中的位置,自上而下进行调度
其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
其会忽略服务器的权重设置
不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
3.2 动态算法
基于后端服务器状态进行调度适当调整,
新请求将优先调度至当前负载较低的服务器
权重可以在haproxy运行时动态调整无需重启
3.2.1 roundrobin
1.基于权重的轮询动态调度算法
2.支持权重的运行时调整,不同于Ivs中的rr轮训模式3.HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数)
4.其每个后端backend中最多支持4095个real server,
5.支持对real server权重动态调整,
6.roundrobin为默认调度算法,此算法使用广泛
会被权重影响可以理解为static-rr的升级版
3.2.2 leastconn
leastconn加权的最少连接的动态
支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客
户端连接)
比较适合长连接的场景使用,比如:MySQL等场景:
balance leastconn
3.3 其他算法
3.3.1 source
源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同-个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改这个算法一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash
3.3.1.1 map-base 取模法
map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。
此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法
balance source
3.3.1.2 一致性hash
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动
该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动
balance source
hash-type consistent
3.3.2 uri
基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后
根据最终结果将请求转发到后端指定服务器
适用于后端是缓存服务器场景
默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash
注意:此算法基于应用层,所以只支持 mode http,不支持 mode tcpuri就类似一个独一无二的身份标识
url就是每次我们输入网址访问某个网站时,浏览器上输入的那一行内容。比如:http://baidu.com这是一个url,每个链接地址是一个url。
- URI = Uniform Resource Identifier 统一资源标志符
- URL = Uniform Resource Locator 统一资源定位符
具体关于url uri的关系本文不做详细解答
balance uri
3.3.3 url_param
url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器,多用于电商通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个realserver如果无没key,将按roundrobin算法
balance uri
hash-type consistent
后续访问不在变换内容
3.3.4 hdr
3.3.4.1 hdr取模法
针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
balance hdr(User-Agent)
3.3.4.2 hdr一致性hash
balance hdr(User-Agent)
hash-type consistent
curl -v
curl -vA s手动更改user-agent
4 高级功能及配置
4.1 基于cookie的会话保持
cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于source 地址hash 调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前此模式使用较少,已经被session共享服务器代替
注意:不支持 tcp mode,使用 http mode
cookie namerewrite insertprefixindirect i[ nocache i postonly]preserve ][httponly ][secure ][ domain ]*[ maxidle <idle> ][ maxlife ]
name:#cookie的key名称,用于实现持久连接insert:#插入新的cookie,默认不插入cookie
indirect:#如果客户端已经有cookie,则不会再发送cookie信息nocache:#当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,#因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器
4.2 haproxy状态页
通过web界面,显示当前HAProxy的运行状态
stats enable#基于默认的参数启用stats page
stats hide-version#将状态页中haproxy版本隐藏
stats refresh <delay>#设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix>#自定义stats page uri,默认值:/haproxy?statsstats auth <user>:<passwd>#认证时的账号和密码,可定义多个用户,每行指定一个用户#默认:no authentication
stats admin{ifunless }<cond> #启用stats page中的管理功能
4.3 ip 透传
web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。
4.3.1 layer7
七层:协议+内容交换
七层负载均衡服务器起了一个反向代理服务器的作用,服务器建立一次TCP连接要三次握手,而client要访问Web Server要先与七层负载设备进行三次握手后建立TCP连接,把要访问的报文信息发送给七层负载均衡;然后七层负载均衡再根据设置的均衡规则选择特定的 Web Server,然后通过三次握手与此台Web Server建立TCP连接,然后Web Server把需要的数据发送给七层负载均衡设备,负载均衡设备再把数据发送给client;所以,七层负载均衡设备起到了代理服务器的作用,七层代理需要和Client和后端服务器分别建立连接
option forwardfor [except <network>][ header <name>][ if-none ]
[except<network>]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络
[header <name>]:使用自定义的首部名称,而非“x-Forwarded-For",示例:X-clien
[if-none ]如果没有首部才添加首部,如果有使用默认值
正常情况下的日志
在由haproxy发往后端主机的请求报文中添加"X-Forwarded-For"首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP
4.3.2 layer4
四层:IP+PORT转发
在四层负载设备中,把client发送的报文目标地址(原来是负载均衡设备的IP地址),根据均衡设备设置的选择web服务器的规则选择对应的web服务器IP地址,这样client就可以直接跟此服务器建立TCP连接并发送数据,而四层负载自身不参与建立连接,而和LVS不同,haproxy是伪四层负载均衡,因为haproxy需要分别和前端客户端及后端服务器建立连接
4.4 ACL
访问控制列表ACL,Access ControlLists)
是一种基于包过滤的访问控制技术
它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配)即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许其通过或丢弃。
4.4.1 acl的选项配置
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型#ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写
#定义ACL匹配规范,即:判断条件
hdr string,提取在一个HTTP请求报文的首部
hdr([<name>[,<occ>]]):完全匹配字符串,header的指定信息,<occ>表示在多值中使用的值的出现次数
hdr_beg([<name>[,<occ>]]):前缀匹配,header中指定匹配内容的beginhdr_end([<name>[,<occ>]]):后缀匹配,header中指定匹配内容end
hdr_dom([<name>[,<oCC>]]):域匹配,header中的domainname(host)
hdr_dir([<name>[,<0CC>]]):路径匹配,header的uri路径
hdr_len([<name>[,<occ>]]):长度匹配,header的长度匹配
hdr_reg([<name>[,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name>[,<occ>]]):子串匹配,header中的uri模糊匹配 模糊匹配c 洪湖报文中a/b/c
也会匹配base 同理
base :string
#返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>path 同理
path :string
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>url 同理
url :string
#提取请求中的整个URL。一个典型的应用是具有预取能力的缓存,以及需要从数据库聚合多个信息并将它们保存在缓存中的网页门户入口,推荐使用path
#ACL匹配模式
-i不区分大小写
-m 使用指定的正则表达式匹配方法
-n 不做DNS解析
-u禁止ac1重名,否则多个同名ACL匹配或关系
ACL 操作符
整数比较:eq、ge、gt、1e、1t
字符比较:
-exact match (-m str):字符串必须完全匹配模式
-substring match(m sub):在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配-prefix match (-m beg):在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
-suffix match (-mend):将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
-subdir match (-m dir):查看提取出来的用斜线分隔(“/")的字符串,如其中任一个匹配,则ACL进行匹配
domain match (-m dom):查找提取的用点(“.")分隔字符串,如果其中任何一个匹配,则ACL进-行匹配
value的类型
The ACL engine can match these types against patterns of the following types :
-Boolean #布尔值
-integer or integer range #整数或整数范围,比如用于匹配端口范围
-IP address/network#IP地址或IP范围,192.168.0.1,192.168.0.1/24-string-->www.timinglee.org
exact#精确比较
substring#子串
suffix#后缀比较
prefix#前缀比较
subdir#路径,/wp-includes/js/jquery/jquery.js
domain#域名,www.timinglee.org
-regular expression#正则表达式
-hex block#16进制
多个ACL的逻辑处理
与:隐式(默认)使用
或:使用“or”或“||"表示
否定:使用"!”表示if
if !