简介
HAProxy是使用C语言开发的一个开源软件,是一款具备高并发(一万以上)、高性能的TCP和HTTP负载均衡器,支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计。
官方站点
功能
支持功能
TCP 和 HTTP反向代理
SSL/TSL服务器
可以针对HTTP请求添加cookie,进行路由后端服务器
可平衡负载至后端服务器,并支持持久连接
支持所有主服务器故障切换至备用服务器
支持专用端口实现监控服务
支持停止接受新连接请求,而不影响现有连接
可以在双向添加,修改或删除HTTP报文首部
响应报文压缩 支持基于pattern实现连接请求的访问控制
通过特定的URI为授权用户提供详细的状态信息
支持http反向代理
支持动态程序的反向代理
支持基于数据库的反向代理
不支持的功能
正向代理--squid,nginx
缓存代理--varnish
web服务--nginx、tengine、apache、php、tomcat
UDP--目前不支持UDP协议
单机性能--相比LVS性能较差
体系结构
编译安装
软件包 | 版本 |
---|---|
HAProxy | haproxy-2.2.9 社区版 |
LUA | lua-5.4.0 |
HAProxy源码包下载地址:http://www.haproxy.org/download/
HAproxy依赖的Lua环境
HAProxy 支持基于lua实现功能扩展,lua是一种脚本语言,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 官网:www.lua.org
Lua 应用场景
游戏开发
独立应用脚本
Web 应用脚本
扩展和数据库插件,如MySQL Proxy
安全系统,如入侵检测系统
Centos 基础环境
参考链接:http://www.lua.org/start.htm
CentOS7 自带的lua版本比较低并不符合HAProxy要求的lua最低版本(5.3)的要求,因此需要编译安装较新版本的lua环境,然后才能编译安装HAProxy,
Lua编译安装
1、安装编译环境与lua
[root@node1 ~]# yum install gcc readline-devel -y
[root@node1 ~]# wget -c http://www.lua.org/ftp/lua-5.4.0.tar.gz
2、进行lua编译
[root@node1 ~]# cd /usr/local/src/lua-5.4.0/
[root@node1 lua-5.4.0]# make linux test
3、查看lua版本
[root@node1 lua-5.4.0]# src/lua -v
Lua 5.4.0 Copyright (C) 1994-2020 Lua.org, PUC-Rio
HAproxy编译安装
1、HAProxy 2.0以上版本编译参数:本文使用的是社区版2.2.9
[root@node1 ~]# yum -y install gcc openssl-devel pcre-devel systemd-devel
[root@node1 ~]# wget -c https://www.haproxy.org/download/2.2/src/haproxy-2.2.9.tar.gz
[root@node1 ~]# tar xf haproxy-2.2.9.tar.gz -C /usr/local/src/
2、安装可以参考/usr/local/src/haproxy-2.2.9/INSTALL文件,文件中要求make>=3.80版本,gcc>=3.4版本
查看make与gcc版本
[root@node1 haproxy-2.2.9]# rpm -q make
make-3.82-24.el7.x86_64
[root@node1 haproxy-2.2.9]# rpm -q gcc
gcc-4.8.5-44.el7.x86_64
3、参考INSTALL文件进行编译安装
[root@node1 haproxy-2.2.9]# make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/src/lua-5.4.0/src/ LUA_LIB=/usr/local/src/lua-5.4.0/src/
[root@node1 haproxy-2.2.9]# make install PREFIX=/usr/local/src/haproxy
4、将命令目录连接到/usr/sbin/目录下,可以直接使用haproxy命令
[root@node1 haproxy-2.2.9]# ln -sv /usr/local/src/haproxy/sbin/haproxy /usr/sbin/
"/usr/sbin/haproxy" -> "/usr/local/src/haproxy/sbin/haproxy"
5、查看haproxy版本
[root@node1 haproxy-2.2.9]# haproxy -v
HA-Proxy version 2.2.9-a947cc2 2021/02/06 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2025.
Known bugs: http://www.haproxy.org/bugs/bugs-2.2.9.html
Running on: Linux 3.10.0-1062.el7.x86_64 #1 SMP Wed Aug 7 18:08:02 UTC 2019 x86_64
haproxy -V 查看参数
haproxy -vv 可查看编译中的选项
haproxy -v
HAProxy启动脚本
[root@node1 ~]# vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target
HAProxy配置文件
global #全局配置参数
maxconn 100000 #最大连接数
chroot /usr/local/src/haproxy #haproxy连接目录
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin #套接字
#uid 99
#gid 99
user haproxy #用户
group haproxy #组
daemon #守护进程的方式
#nbproc 1
#cpu-map 1 0
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid #pid文件
log 127.0.0.1 local2 info #日志级别
defaults #默认配置参数
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms #超时时间
timeout client 300000ms
timeout server 300000ms
listen stats #监听状态
mode http #模式
bind 0.0.0.0:9999 #绑定本地所有IP地址的9999端口
stats enable
log global #全局日志记录
stats uri /haproxy-status
stats auth haadmin:123456 #认证:用户名:密码
[root@node1 ~]# mkdir /var/lib/haproxy
[root@node1 ~]# useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy
[root@node1 ~]# systemctl start haproxy
查看haproxy的状态页面
浏览器访问: http://192.168.16.11:9999/haproxy-status
登录用户名密码访问,用户名密码在配置文件中 listen stats
字段中已设置
HAProxy 的配置文件haproxy.cfg
由两大部分组成,分别是global
和proxies
部分
global:全局配置段
进程及安全配置相关的参数
性能调整相关参数
Debug参数
官方文档 global配置说明:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#3
1、global 配置部分参数说明:
chroot #锁定运行目录
deamon #以守护进程运行
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin process 1
#socket文件
user, group, uid, gid #运行haproxy的用户身份
nbproc n #开启的haproxy work 进程数,默认进程数是一个
#nbthread 1 #指定每个haproxy进程开启的线程数,默认为每个进程一个线程,和nbproc互斥(版本有关)
如果同时启用nbproc和nbthread 会出现以下日志的错误,无法启动服务
#Apr 7 14:46:23 haproxy haproxy: [ALERT] 097/144623 (1454) : config : cannot enable multiple processes if multiple threads are configured. Please use either nbproc or nbthread but not both.
cpu-map 1 0 #绑定haproxy 进程至指定CPU,将第一个work进程绑定至0号CPU
maxconn n #每个haproxy进程的最大并发连接数
maxsslconn n #每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
maxconnrate n #每个进程每秒创建的最大连接数量
spread-checks n #后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认值0
pidfile #指定pid文件路径
log 127.0.0.1 local2 info #定义全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个
2、多进程和线程配置
1、编辑配置文件中的global字段
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
global
maxconn 100000
chroot /usr/local/src/haproxy
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1 #守护进程1
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2 #守护进程2
#uid 99
#gid 99
user haproxy
group haproxy
daemon
nbproc 2 #开启的haproxy work 进程数为 2
#cpu-map 1 0
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local2 info
2、重启服务
[root@node1 ~]# systemctl restart haproxy.servic
3、HaProxy日志配置
#在global配置项定义:
global
log 127.0.0.1 local2 info #基于syslog记录日志到指定设备,级别有(err、warning、 info、debug)
listen web_port
bind 127.0.0.1:80
mode http
log global #开启当前web_port的日志功能,默认不记录日志
server web1 127.0.0.1:8080 check inter 3000 fall 2 rise
[root@node1 ~]# vim /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
# Save boot messages also to haproxy.log
local2.* /var/log/haproxy.log
重启日志服务
[root@node1 ~]# systemctl restart rsyslog.service
proxies:代理配置段
defaults:为frontend, backend, listen提供默认配置
frontend:前端,相当于nginx中的server {}
backend:后端,相当于nginx中的upstream {}
listen:同时拥有前端和后端配置
官方文档proxies配置说明:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4
defaults [<name>] #默认配置项,针对以下的frontend、backend和listen生效,可以多个name也 可以没有
name frontend <name> #前端servername,类似于Nginx的一个虚拟主机 server和LVS服务集群。
backend <name> #后端服务器组,等于nginx的upstream和LVS中的RS服务器
listen <name> #将frontend和backend合并在一起配置,相对于frontend和backend配置更简 洁,生产常用
注意:name字段只能使用大小写字母,数字,‘-’(dash),’_‘(underscore),’.’ (dot)和 ‘:'(colon),并且严格区分大小写
1、 Proxies配置-defaults
配置参数:
option redispatch #当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
option abortonclose #当服务器负载很高时,自动结束掉当前队列处理比较久的链接,针对业务情 况选择开启
option http-keep-alive #开启与客户端的会话保持
option forwardfor #透传客户端真实IP至后端web服务器
mode http|tcp #设置默认工作类型,使用TCP服务器性能更好,减少压力
timeout http-keep-alive 120s #session 会话保持超时时间,此时间段内会转发到相同的后端服务器
timeout connect 120s #客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前), 默认单位ms
timeout server 600s #客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后), 默认单位ms,如果超时,会出现502错误,此值建议设置较大些,访止502错误
timeout client 600s #设置haproxy与客户端的最长非活动时间,默认单位ms,建议和timeout server相同
timeout check 5s #对后端服务器的默认检测超时时间
default-server inter 1000 weight 3 #指定后端服务器的默认设置
2、Proxies配置-frontend
配置参数:
bind: #指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中
#格式:
bind [<address>]:<port_range> [, ...] [param*]
注意:如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1
3、Proxies配置-backend
mode http|tcp #指定负载协议类型,和对应的frontend必须一致
option #配置选项
server #定义后端real server
注意:option后面加 httpchk,smtpchk,mysql-check,pgsql-check,ssl-hello-chk方法,可用于实现更多应用层检测功能。
option 配选项说明:
check 对指定real进行健康状态检查,如果不加此设置,默认不开启检查
addr <IP> 可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量
port <num> 指定的健康状态监测端口
inter <num> 健康状态检查间隔时间,默认2000 ms
fall <num> 后端服务器从线上转为线下的检查的连续失效次数,默认为3
rise <num> 后端服务器从下线恢复上线的检查的连续有效次数,默认为2
weight <weight> 默认为1,最大值为256,0表示不参与负载均衡,但仍接受持久连接
backup 将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似 Sorry Server
disabled 将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接
redirect prefix http://www.baidu.com/ 将请求临时(302)重定向至其它URL,只适用于 http模式
redir http://www.baidu.com 将请求临时(302)重定向至其它URL,只适用于 http模式
maxconn <maxconn> 当前后端server的最大并发连接数
backlog <backlog> 当前端服务器的连接数达到上限后的后援队列长度,注意:不支持backend
负载均衡配置
主机名及IP地址 | 角色 |
---|---|
node1:192.168.16.11 | HAproxy |
node2:192.168.16.12 | 服务节点1 |
node3:192.168.16.13 | 服务节点2 |
node4:192.168.16.14 | 测试端 |
内核版本 | 3.10.0-1062.el7.x86_64 |
发行版本 | CentOS Linux release 7.7.1908 (Core) |
基础环境:各服务器关闭防火墙
[root@node1 ~]# systemctl stop firewalld.service
[root@node2 ~]# systemctl stop firewalld.service
[root@node3 ~]# systemctl stop firewalld.service
基于frontend+backend配置实例
1、后端节点配置服务:node2,node3
[root@node2 ~]# yum install httpd -y
[root@node2 ~]# echo "this is a test1 " > /var/www/html/index.html
[root@node2 ~]# systemctl start httpd
[root@node3 ~]# yum install httpd -y
[root@node3 ~]# echo "this is a test2 " > /var/www/html/index.html
[root@node3 ~]# systemctl start httpd
2、haproxy节点配置:node1
1、编辑配置文件
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
global
maxconn 100000
chroot /usr/local/src/haproxy
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
#stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
#uid 99
#gid 99
user haproxy
group haproxy
daemon
#nbproc 2
#cpu-map 1 0
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3
pidfile /var/lib/haproxy/haproxy.pid
log 127.0.0.1 local2 info
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
frontend webserver
mode tcp
bind 192.168.16.11:80
use_backend webpool1
backend webpool1
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
开启内核参数
[root@node1 ~]# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
立即生效
[root@node1 ~]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1
重启服务
[root@node1 ~]# systemctl restart rsyslog.service
3、测试:node4
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11; done
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
基于listen配置实例
1、haproxy节点配置:node1
1、修改配置文件,加入listen配置项
listen web_port
mode tcp
bind :880
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
2、重启服务
[root@node1 ~]# systemctl restart haproxy.service
2、测试:node4
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:880; done
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
基于子配置文件保存配置实例
当业务众多时,将所有配置都放在一个配置文件中,会造成维护困难。可以考虑按业务分类,将配置信息拆分,放在不同的子配置文件中,从而达到方便维护的目的。
haproxy节点配置:node1
1、创建子配置文件的目录
[root@node1 ~]# mkdir /etc/haproxy/conf.d
2、编辑子配置文件
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
3、将子配置文件目录加入到服务启动项中,编辑启动配置文件
[root@node1 ~]# vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target
4、将服务重新加载并启动
[root@node1 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl restart haproxy.service
测试:node4
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:8880; done
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
HAproxy调度算法
HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中。
官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-balance
1、静态算法
按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、链接数和响应速度等,且无法实时修改权重,只能靠重启HAProxy生效,或者使用socat工具
socat工具
参考文件:http://www.dest-unreach.org/socat/doc/socat.html
对服务器动态权重和其它状态的调整,特点就是在两个数据流之间建立通道,且支持众多协议和链接方式。
1、安装socat工具
[root@node1 ~]# yum install socat -y
2、根据配置文件查看服务器的速率
[root@node1 ~]# echo "show servers state" | socat stdio /var/lib/haproxy/haproxy.sock
1
# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord
4 webpool1 1 web1 192.168.16.12 2 0 1 1 14151 6 3 4 6 0 0 0 - 80 -
4 webpool1 2 web2 192.168.16.13 2 0 1 1 14151 6 3 4 6 0 0 0 - 80 -
5 web_port 1 web1 192.168.16.12 2 0 1 1 14151 6 3 4 6 0 0 0 - 80 -
5 web_port 2 web2 192.168.16.13 2 0 1 1 14151 6 3 4 6 0 0 0 - 80 -
6 web01 1 web1 192.168.16.12 2 0 1 1 14151 6 3 4 6 0 0 0 - 80 -
6 web01 2 web2 192.168.16.13 2 0 1 1 14151 6 3 4 6 0 0 0 - 80 -
3、获取权值
[root@node1 ~]# echo "get weight web01/web1" | socat stdio /var/lib/haproxy/haproxy.sock
1 (initial
4、修改weight,针对单进程有效
[root@node1 ~]# echo "set weight web01/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock
5、若后端服务器需要处理,可将后端服务器禁用,针对单线程
[root@node1 ~]# echo "disable server web01/web1" | socat stdio /var/lib/haproxy/haproxy.sock
6、将后端服务器weight设置为0,不参与负载均衡
[root@node1 ~]# echo "get weight web01/web1 0" | socat stdio /var/lib/haproxy/haproxy.sock
7、开启后端禁用的服务器,针对单线程
[root@node1 ~]# echo "enable server web01/web1" | socat stdio /var/lib/haproxy/haproxy.sock
8、将后端服务器禁用,针对多进程
首先将配置文件中多线程的规律性找出,将一个不同处设置为一个变量
[root@centos7 ~]# vim /etc/haproxy/haproxy.cfg
......
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
stats socket /var/lib/haproxy/haproxy.sock3 mode 600 level admin process 3
stats socket /var/lib/haproxy/haproxy.sock4 mode 600 level admin process 4
nbproc 4
.....
可以逐个进行单线程禁用,也可使用for循环语句及变量进行多线程禁用。
[root@node1 ~]# for ((i=1;i<=4;i++))
> do
> echo "disable server web01/webi" | socat stdio /var/lib/haproxy/haproxyi.socki
> done
静态算法的weight只能更改为0或1,否则会有以下提示信息:
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
static-rr(加权轮询)
基于权重的轮询调度,不支持权重的运行时利用socat进行动态调整及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr
编辑配置文件
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
balance static-rr
server web1 192.168.16.12:80 weight 1 check
server web2 192.168.16.13:80 weight 2 check
重启服务
[root@node1 ~]# systemctl restart haproxy.service
测试:静态算法的weight只能更改为0或1
[root@node1 ~]# echo "set weight web_port/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
测试:
[root@node1 ~]# echo "get weight web01/web1" | socat stdio /var/lib/haproxy/haproxy.sock
1 (initial 1)
[root@node1 ~]# echo "get weight web01/web2" | socat stdio /var/lib/haproxy/haproxy.sock
2 (initial 2)
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:8880; done
this is a test1
this is a test2
this is a test2
this is a test1
this is a test2
this is a test2
this is a test1
this is a test2
this is a test2
this is a test1
first
根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少
编辑配置文件
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
balance first
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
重启服务
[root@node1 ~]# systemctl restart haproxy.service
测试:
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:8880; done
this is a test1
this is a test1
this is a test1
this is a test1
this is a test1
this is a test1
this is a test1
this is a test1
this is a test1
this is a test1
2、动态算法
基于后端服务器状态进行调度适当调整,优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。
roundrobin(轮询算法)HAproxy默认调度算法
基于权重的轮询动态调度算法
支持权重的运行时调整
支持慢启动(新加的服务器会逐渐增加转发数)
backend中最多支持4095个real server
支持对real server权重动态调整,可以使用socat进行调整。
编辑配置文件
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
balance roundrobin
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
重启服务
[root@node1 ~]# systemctl restart haproxy.service
测试:
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:8880; done
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
leastconn(最少连接)
支持权重的运行时调整和慢启动,即当前后端服务器连接最少的优先调度(新客户端连接),比较适合长连接的场景使用。
编辑配置文件
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
balance leastconn
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
重启服务
[root@node1 ~]# systemctl restart haproxy.service
测试:
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:8880; done
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
random(负载平衡)
基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用
支持weight的动态调整,weight较大的主机有更大概率获取新请求。
编辑配置文件
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
balance random
server web1 192.168.16.12:80 weight 1 check
server web2 192.168.16.13:80 weight 5 check
重启服务:
[root@node1 ~]# systemctl restart haproxy.service
测试:
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:8880; done
this is a test1
this is a test2
this is a test2
this is a test2
this is a test1
this is a test2
this is a test2
this is a test2
this is a test2
this is a test2
3、其他算法(可静可动)
可以作为静态算法,也可通过选项称为动态算法
(1)source算法(源地址hash)
基于用户源地址hash并将请求转发到一个后端服务器,后续同一个源请求将是同一个服务器进行服务。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器。
默认静态方式,可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
源地址选取后端服务器的计算方式:
计算方法一:map-based(取模法)
对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。
该算法是静态的
不支持在线调整权重
不支持慢启动,可实现对后端服务器均衡调度
缺点
当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 默认该算法
计算方法二:一致性hash
当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,
该算法是动态的
支持在线权重调整,可使用 socat
支持慢启动
基于source算法,hash-type为map-based:
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
balance source
hash-type map-based
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
[root@node1 ~]# systemctl restart haproxy.service
[root@node1 ~]# echo "set weight web01/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
基于source算法,hash-type为consistent:
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode tcp
bind :8880
balance source
hash-type consistent
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
[root@node1 ~]# systemctl restart haproxy.service
[root@node1 ~]# echo "set weight web01/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock
(2)URI算法
基于对用户请求的URI的左半部分或整个URI做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景。
默认是静态,可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
此算法是应用层,所有只支持 mode http ,不支持 mode tcp
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
左半部分:/<path>;<params>
整个uri:/<path>;<params>?<query>#<frag>
基于uri算法,hash-type为map-based:
listen web01
mode http #只能为http类型
bind :8880
balance uri
hash-type map-based
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
基于uri算法,hash-type为map-based:
listen web01
mode http
bind :8880
balance uri
hash-type consistent
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
(3)url_param算法
基于对用户请求的URI中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server。
如果无key,将按默认的roundrobin算法
此算法是应用层,所有只支持 mode http ,不支持 mode tcp
假设: url = http://www.openlab.com/foo/bar/index.php?key=value
则:
host = "www.openlab.com"
url_param = "key=value"
基于url_param算法,hash-type为map-based:
listen web01
mode http
bind :8880
balance url_param userid
hash-type map-based
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
基于url_param算法,hash-type为consistent:
listen web01
mode http
bind :8880
balance url_param userid
hash-type consistent
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
(4)hdr算法
基于用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器。
如无有效的值,则会使用默认的轮询调度。
此算法是应用层,所有只支持 mode http ,不支持 mode tcp
基于hdr算法,hash-type为map-based:
listen web01
mode http
bind :8880
balance har(User-Agent) #根据浏览器类型进行hash
hash-type map-based
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
基于hdr算法,hash-type为consistent:
listen web01
mode http
bind :8880
balance har(User-Agent)
hash-type consistent
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
重启服务后测试:
[root@node4 ~]# curl -v 192.168.16.11:8880
* About to connect() to 192.168.16.11 port 8880 (#0)
* Trying 192.168.16.11...
* Connected to 192.168.16.11 (192.168.16.11) port 8880 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.16.11:8880
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Fri, 26 Feb 2021 13:54:10 GMT
< server: Apache/2.4.6 (CentOS)
< last-modified: Fri, 26 Feb 2021 05:01:25 GMT
< etag: "11-5bc3629028f97"
< accept-ranges: bytes
< content-length: 17
< content-type: text/html; charset=UTF-8
<
this is a test1
[root@node4 ~]# curl -vA "chrome" 192.168.16.11:8880
* About to connect() to 192.168.16.11 port 8880 (#0)
* Trying 192.168.16.11...
* Connected to 192.168.16.11 (192.168.16.11) port 8880 (#0)
> GET / HTTP/1.1
> User-Agent: chrome
> Host: 192.168.16.11:8880
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Fri, 26 Feb 2021 13:53:36 GMT
< server: Apache/2.4.6 (CentOS)
< last-modified: Fri, 26 Feb 2021 05:01:38 GMT
< etag: "11-5bc3629caea7f"
< accept-ranges: bytes
< content-length: 17
< content-type: text/html; charset=UTF-8
<
this is a test2
[root@node4 ~]# curl -vA "firefox" 192.168.16.11:8880
* About to connect() to 192.168.16.11 port 8880 (#0)
* Trying 192.168.16.11...
* Connected to 192.168.16.11 (192.168.16.11) port 8880 (#0)
> GET / HTTP/1.1
> User-Agent: firefox
> Host: 192.168.16.11:8880
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Fri, 26 Feb 2021 13:53:08 GMT
< server: Apache/2.4.6 (CentOS)
< last-modified: Fri, 26 Feb 2021 05:01:25 GMT
< etag: "11-5bc3629028f97"
< accept-ranges: bytes
< content-length: 17
< content-type: text/html; charset=UTF-8
<
this is a test1
(5)rdp-cookie
对windows远程桌面的负载,使用cookie保持会话
默认是静态,可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash
此算法支持 mode tcp ,不支持 mode http
基于rdp-cookie算法,hash-type为map-based:
listen web01
mode http
bind :8880
balance rdp-cookie
hash-type map-based
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
基于rdp-cookie算法,hash-type为consistent:
listen web01
mode http
bind :8880
balance rdp-cookie
hash-type consistent
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
HAproxy高级功能
1、基于cookie的会话保持
cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址hash 调度算法对客户端的粒度更精准,但同时也加大了haproxy负载。
不支持 tcp mode,支持 http mode
参数说明
cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [ preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
name: #cookie 的key名称,用于实现持久连接
insert: #插入新的cookie,默认不插入cookie
indirect: #如果客户端已经有cookie,则不会再发送cookie信息
nocache:
#当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie, 因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器
基于cookie编辑配置文件:node1
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode http #不支持 tcp,支持 http
bind :8880
balance roundrobin #默认roundrobin
log global #全局日志
cookie webser insert nocache indirect #cookie相关配置
server web1 192.168.16.12:80 check cookie web1
server web2 192.168.16.13:80 check cookie web1
[root@node1 ~]# systemctl restart haproxy.service
测试:node4
[root@node4 ~]# curl -i 192.168.16.11:8880
HTTP/1.1 200 OK
date: Sun, 28 Feb 2021 01:22:25 GMT
server: Apache/2.4.6 (CentOS)
last-modified: Fri, 26 Feb 2021 05:01:25 GMT
etag: "11-5bc3629028f97"
accept-ranges: bytes
content-length: 17
content-type: text/html; charset=UTF-8
set-cookie: web01=web1; path=/ #cookie信息
cache-control: private
this is a test1
[root@node4 ~]# curl -i 192.168.16.11:8880
HTTP/1.1 200 OK
date: Sun, 28 Feb 2021 01:22:28 GMT
server: Apache/2.4.6 (CentOS)
last-modified: Fri, 26 Feb 2021 05:01:38 GMT
etag: "11-5bc3629caea7f"
accept-ranges: bytes
content-length: 17
content-type: text/html; charset=UTF-8
set-cookie: web01=web1; path=/ #cookie信息
cache-control: private
this is a test2
基于cookie指定后端的服务名查看对应网页信息
[root@node4 ~]# curl -b webser=web1 192.168.16.11:8880
this is a test1
[root@node4 ~]# curl -b webser=web2 192.168.16.11:8880
this is a test1
2、HAProxy状态页
通过web界面,显示当前HAProxy的运行状态:
官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-stats%20admin
配置文件中参数说明:
stats enable #基于默认的参数启用stats page
stats hide-version #将状态页中haproxy版本隐藏
stats refresh <delay> #设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> #自定义stats page uri,默认值:/haproxy?stats
stats realm <realm> #账户认证时的提示信息,示例:stats realm HAProxy\ Statistics
stats auth <user>:<passwd> #认证时的账号和密码,可使用多次,默认:no authentication, 可有多行用户
stats admin { if | unless } <cond> #启用stats page中的管理功能
(1)版本隐藏示例,修改 listen stats配置项
配置修改前页面
隐藏版本信息配置:
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
stats hide-version #添加该配置项
[root@node1 ~]# systemctl restart haproxy.service
配置修改后页面隐藏了版本信息
(2)自定义uri示例,修改 listen stats配置项
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
stats hide-version
stats uri /status-page #自定义uri命名
[root@node1 ~]# systemctl restart haproxy.service
(3)启用状态页管理功能,修改 listen stats配置项
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
stats hide-version
stats uri /status-page
stats admin if TRUE #编译该配置项
[root@node1 ~]# systemctl restart haproxy.service
状态页面参数说明
pid = 1991 (process #1, nbproc = 1, nbthread = 1)
#pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程
uptime = 0d 0h00m04s #启动了多长时间
system limits: memmax = unlimited; ulimit-n = 200044
#系统资源限制:内存;最大打开文件数
maxsock = 200044; maxconn = 100000; maxpipes = 0
#最大socket连接数;单进程最大连接数; 最大管道数
current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps
#当前连接数;当前管道数;当前连接速率
Running tasks: 1/26; idle = 100 %
#运行的任务;当前空闲率
active UP: #在线服务器
backup UP: #标记为backup的服务器
active UP, going down #监测未通过正在进入down过程
backup UP, going down #备份服务器正在进入down过程
active DOWN, going up #down的服务器正在进入up过程
backup DOWN, going up #备份服务器正在进入up过程
active or backup DOWN #在线的服务器或者是backup的服务器已经转换成了 down状态
not checked #标记为不监测的服务器
active or backup DOWN for maintenance (MAINT)
#active或者backup服务器人为下线的
active or backup SOFT STOPPED for maintenance
#active或者backup被人为软下线(人为将 weight改成0)
backend 信息说明
session rate(每秒的连接会话信息):
cur: 每秒的当前会话数量
max: 每秒新的最大会话数量
limit: 每秒新的会话限制量
sessions(会话信息):
cur: 当前会话量
max: 最大会话量
limit: 限制会话量
Total: 总共会话量
LBTot: 选中一台服务器所用的总时间
Last: 和服务器的持续连接时间
Wght: 权重
Bytes(流量统计):
In: 网络的字节输入总量
Out: 网络的字节输出总量
Denied(拒绝统计信息):
Req: 拒绝请求量
Resp: 拒绝回复量
Errors(错误统计信息):
Req: 错误请求量
conn: 错误链接量
Resp: 错误响应量
Warnings(警告统计信息):
Retr: 重新尝试次数
Redis: 再次发送次数
Server(real server信息):
Status: 后端机的状态,包括UP和DOWN
LastChk: 持续检查后端服务器的时间
Act: 活动链接数量
Bck: 备份的服务器数量
Chk: 心跳检测时间
Dwn: 后端服务器连接后都是DOWN的数量
Dwntme: 总的downtime时间
Thrtle: server 状态
3、IP透传
IP透传目的:记录客户端的真实IP地址,用户访问的统计、安全维护、行为分析等
(1)四层IP透传配置:
修改后端服务器的全局日志格式:
[root@node2 ~]# vim /etc/httpd/conf/httpd.conf
# LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
[root@node2 ~]# systemctl restart httpd
访问测试:node4
[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11:8880 ; done
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
this is a test2
this is a test1
后端服务器查看日志
[root@node2 ~]# tail -3 /var/log/httpd/access_log
192.168.16.14 - [28/Feb/2021:11:24:46 +0800] "GET / HTTP/1.1" 200 17 "-" "curl/7.29.0"
192.168.16.14 - [28/Feb/2021:11:24:46 +0800] "GET / HTTP/1.1" 200 17 "-" "curl/7.29.0"
192.168.16.14 - [28/Feb/2021:11:24:46 +0800] "GET / HTTP/1.1" 200 17 "-" "curl/7.29.0"
(2)七层IP透传配置:
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For”首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
[ except <network> ]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络
[ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For”
[ if-none ] 如果没有首部才添加首部,如果有使用默认值
下载扩展源
[root@node6 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
4、报文修改
在http模式下,基于实际需求修改客户端的请求报文与响应报文,通过reqadd和reqdel在请求报文添加删除字段,通过rspadd与rspidel在响应报文中添加与删除字段。
官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4-http-request
http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4-http-response
5、自定义日志格式
log global 开启日志功能,默认只会在记录下面格式的日志
[root@node1 ~]# tail -1 /var/log/haproxy.log
Feb 28 20:16:38 localhost haproxy[3068]: Connect from 192.168.16.14:46656 to 192.168.16.11:8880 (web01/HTTP)
option httplog 可以将http格式记录下,并且可以使用相关指令将特定信息记录在haproxy的日志中,一般不建议开启,这会加重 HAProxy 负载
配置选项:
log global #开启记录日志,默认不开启
option httplog #开启记录httplog日志格式选项
capture cookie <name> len <length> #捕获请求和响应报文中的cookie并记录日志
capture request header <name> len <length> #捕获请求报文中指定的首部内容和长度并记录日志
capture response header <name> len <length> #捕获响应报文中指定的内容和长度首部并记录日志
haproxy端修改日志格式参数:node1
listen web01
mode http
bind :8880
balance roundrobin
log global
option httplog
capture request header Host len 256 capture request header User-Agent len 512 capture request header Referer len 15
capture request header X-Forwarded-For len 15
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
测试:node4
[root@node4 ~]# for ((i=1;i<=2;i++)); do curl 192.168.16.11:8880 ; done
this is a test1
this is a test2
haproxy端查看日志:node1
[root@node1 ~]# tail -1 /var/log/haproxy.log
Feb 28 20:49:11 localhost haproxy[3211]: 192.168.16.14:46700 [28/Feb/2021:20:49:11.424] web01 web01/web2 0/0/0/1/1 200 250 - - ---- 1/1/0/0/0 0/0 {192.168.16.11:8880|curl/7.29.0||} "GET / HTTP/1.1"
6、HAProxy压缩功能
对响应给客户端的报文进行压缩,以节省网络带宽,但是会占用部分CPU性能,建议在后端服务器开启压缩功能,而非在HAProxy上开启压缩
配置选项:
compression algo <algorithm> ... #启用http协议中的压缩机制,常用算法有gzip,deflate
<algorithm>支持下面类型:
identity #debug调试使用的压缩方式
gzip #常用的压缩方式,与各浏览器兼容较好
deflate #有些浏览器不支持
raw-deflate #新式的压缩方式
compression type <mime type> ... #要压缩的文件类型
haproxy服务器配置压缩参数:node1
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
listen web01
mode http
bind :8880
balance roundrobin
log global
option httplog
compression algo gzip deflate
compression type compression type text/plain text/html text/css text/xml text/javascript application/javascript
server web1 192.168.16.12:80 check
server web2 192.168.16.13:80 check
[root@node1 ~]# systemctl restart haproxy.service
后端服务器准备文件:node3
[root@node3 ~]# cat /var/www/html/index.html
this is a test2
测试:node4
[root@node4 ~]# curl -is --compressed 192.168.16.11:8880/index.html
HTTP/1.1 200 OK
date: Sun, 28 Feb 2021 12:41:15 GMT
server: Apache/2.4.6 (CentOS)
last-modified: Fri, 26 Feb 2021 05:01:25 GMT
etag: W/"11-5bc3629028f97"
accept-ranges: bytes
content-type: text/html; charset=UTF-8
content-encoding: deflate
transfer-encoding: chunked
vary: Accept-Encoding
this is a test1
7、web服务检测状态
三种状态监测方式
基于四层的tcp端口做状态监测,此为默认方式
基于指定 URI 做状态监测
基于指定 URI 的request请求头部内容做状态监测
(1)基于tcp端口的健康检查配置
- inter : 2000 不加该参数,正常情况默认每两秒检查一次。
- rise : 2 不加该参数,在RS宕机后恢复前,检查2次OK,认为其复合,并加入集群组中
- fall : 3 不加该参数,检查3此后,认为RS宕机,剔除集群组
- port : default server port 不加该参数,默认就是端口检查
- addr : specific address for the test (default = address server)
- maxconn :2048 最大连接数,
- weight :12 权重
编辑配置文件中健康检查参数
listen web01
mode tcp
bind :8880
balance roundrobin
log global
option httpchk
server web1 192.168.16.12:80 check port 80 inter 5000 fall 5
server web2 192.168.16.13:80 check port 80 inter 5000 fall 5
[root@node1 ~]# systemctl restart haproxy.service
(2) 基于HTTP的直接IP URL方式的健康检查
第一种HEAD配置方式
1)修改配置文件中健康检查选项
option httpchk HEAD /index.html HTTP/1.0
2)重启haproxy服务
[root@node1 ~]# systemctl restart haproxy.service
3)查看haproxy页面状态
第二种GET配置方法
1)修改配置文件中健康检查选项
option httpchk GET /index.html
2)重启haproxy服务
[root@node1 ~]# systemctl restart haproxy.service
3)查看haproxy页面状态
8、ACL
访问控制列表(ACL,Access Control Lists)是一种基于包过滤的访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配),即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许其通过或丢弃。
官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#7
http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#7
格式:
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
criterion
hdr string
#提取在一个HTTP请求报文的首部
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出现次数
hdr_beg([<name> [,<occ>]]):前缀匹配,header中指定匹配内容的begin
hdr_end([<name> [,<occ>]]):后缀匹配,header中指定匹配内容end
hdr_dom([<name> [,<occ>]]):域匹配,header中的domain name
hdr_dir([<name> [,<occ>]]):路径匹配,header的uri路径
hdr_len([<name> [,<occ>]]):长度匹配,header的长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):子串匹配,header中的uri模糊匹配
base : string
#返回第一个主机头和请求的路径部分的连接,该请求从第一个斜杠开始,并在问号之前结束,对虚拟主机有用
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
base : exact string match
base_beg : prefix match
base_dir : subdir match
base_dom : domain match
base_end : suffix match
base_len : length match
base_reg : regex match
base_sub : substring match
path : string
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>
path : exact string match
path_beg : prefix match #请求的URL开头
path_end : suffix match #请求的URL中资源的结尾
path_dom : domain match
path_dir : subdir match
path_len : length match
path_reg : regex match
path_sub : substring match
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
dst #目标IP
dst_port #目标PORT
src #源IP
src_port #源PORT
flags
-i 不区分大小写
-m 使用指定的pattern匹配方法
-n 不做DNS解析
-u 禁止acl重名,否则多个同名ACL匹配或关系
operato(操作符)
整数比较:eq、ge、gt、le、lt
字符比较:
- exact match (-m str) :字符串必须完全匹配模式
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹 配
- suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
- subdir match (-m dir) :查看提取出来的用斜线分隔(“/”)的字符串,如其中任一个匹配,则ACL进行匹配
- domain match (-m dom) :查找提取的用点(“.”)分隔字符串,如果其中任何一个匹配,则ACL进行匹配
value
- Boolean #布尔值
- integer or integer range #整数或整数范围,比如用于匹配端口范围
- IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
- string--> www.openlab.com
exact –精确比较
substring—子串
suffix-后缀比较
prefix-前缀比较
subdir-路径, #/wp-includes/js/jquery/jquery.js
domain-域名, #www.openlab.com
- regular expression #正则表达式
- hex block #16进制
ACL调用方式:
与: 隐式(默认)使用
或: 使用“or” 或 “||”表示
否定: 使用 "!" 表示
例:匹配访问路径实现动静分离
后端服务器网页配置:node2,node3
[root@node2 ~]# mkdir /var/www/html/static
[root@node2 ~]# echo "静态页面" > /var/www/html/static/index.html
[root@node3 ~]# mkdir /var/www/html/dynamic
[root@node3 ~]# [root@node3 ~]# echo "动态页面" > /var/www/html/dynamic/index.html
haproxy端配置文件编辑:node1
[root@node1 ~]# vim /etc/haproxy/conf.d/web01.cfg
frontend http
bind :8880
option http-keep-alive
timeout http-keep-alive 30s
acl static path_beg -i /static
acl static path_reg -i ^/.+.(js|css|ico|bmp|jpg|jpeg|png|swf|cur|html)$
acl dynamic path_beg -i /dynamic
acl dynamic path_reg -i ^/.+.(php|jsp|html)$
use_backend static_pool if staticv
use_backend dynamic_pool if dynamic
default_backend dynamic_pool
backend static_pool
server static_page 192.168.16.12:80 check
backend dynamic_pool
server dynamic_page 192.168.16.13:80 check
[root@node1 ~]# systemctl restart haproxy.service
测试:node4
[root@node4 ~]# curl 192.168.16.11:8880/dynamic/
动态页面
[root@node4 ~]# curl 192.168.16.11:8880/static/
静态页面
9、自定义HAProxy错误界面
使用errorfile和errorloc指令,可以自定义各种错误页面
自定义错误页
errorfile <code> <file>
<code> #HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504
<file> #包含完整HTTP响应的错误页文件的绝对路径。 建议后缀“ .http”,以和一般的html文件相区分
错误页面重定向
errorloc <code> <url>
#相当于errorloc302 <code> <url>,利用302重定向至指URL
编辑自定义错误页面配置:node1
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
defaults
option http-keep-alive
option forwardfor except 192.168.16.0/24
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
errorfile 503 /usr/local/src/haproxy/html/503.http
创建文件存放目录及编辑网页内容:node1
[root@node1 ~]# mkdir /usr/local/src/haproxy/html -p
[root@node1 ~]# vim /usr/local/src/haproxy/html/503.http
HTTP/1.1 503 Service Unavailable
Content-Type:text/html;charset=utf-8
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>报错页面</title>
</head>
<body>
<center><h1>网站维护中......请稍侯再试</h1>
</center> <center><h2>联系电话:400-123-4567</h2>
</center> <center><h3>503 Service Unavailable</h3></center>
</body>
重启服务
[root@node1 ~]# systemctl restart haproxy.service
10、HAProxy后端不参与负载
编辑配置文件:node1
[root@node1 ~]# vim /etc/haproxy/haproxy.cfg
frontend webserver
mode tcp
bind 192.168.16.11:80
use_backend webpool1
backend webpool1
server web1 192.168.16.12:80 check backup #添加backup参数
server web2 192.168.16.13:80 check
测试:node4
在这里插入代码片[root@node4 ~]# for ((i=1;i<=10;i++)); do curl 192.168.16.11 ; done
动态页面
动态页面
动态页面
动态页面
动态页面
动态页面
动态页面
动态页面
动态页面
动态页面