一、工作原理
(1)包括
- 监听端口:HAProxy 会在指定的端口上监听客户端的请求。 例如,它可以监听常见的 HTTP 和 HTTPS 端口,等待客户端连接。
- 请求接收:当客户端发起请求时,HAProxy 接收到请求。 它会解析请求的内容,包括请求的方法(如 GET、POST 等)、目标 URL 等。
- 负载均衡决策:根据预先配置的负载均衡策略,决定将请求转发到后端的哪个服务器。 常见的负载均衡算法有轮询、加权轮询、最少连接等。 比如,轮询算法会依次将请求均匀地分配到后端的服务器;加权轮询则会根据服务器的权重来分配请求。
- 健康检查:HAProxy 会持续监测后端服务器的健康状态。 通过发送特定的请求或者检测服务器的响应来判断服务器是否正常工作。 如果发现某台服务器不可用,它会自动将请求转发到其他正常的服务器上。
- 请求转发:确定目标服务器后,将客户端的请求转发给该服务器。
- 响应处理:后端服务器处理请求并返回响应给 HAProxy。
- 响应返回:HAProxy 再将后端服务器的响应返回给客户端。
(2)负载均衡
1、为什么使用负载均衡?
- Web服务器的动态水平扩展-->对用户无感知
- 增加业务并发访问及处理能力-->解决单服务器瓶颈问题
- 节约公网IP地址-->降低IT支出成本
- 隐藏内部服务器IP-->提高内部服务器安全性
- 配置简单-->固定格式的配置文件
- 功能丰富-->支持四层和七层,支持动态下线主机
- 性能较强-->并发数万甚至数十万
2、四层负载均衡
通过ip+port决定负载均衡的去向。
对流量请求进行NAT处理,转发至后台服务器。
记录tcp、udp流量分别是由哪台服务器处理,后续该请求连接的流量都通过该服务器处理。
支持四层的软件
- lvs:重量级四层负载均衡器。
- Nginx:轻量级四层负载均衡器,可缓存。(nginx四层是通过upstream模块)
- Haproxy:模拟四层转发。
3、七层负载均衡
通过虚拟ur|或主机ip进行流量识别,根据应用层信息进行解析,决定是否需要进行负载均衡。
代理后台服务器与客户端建立连接,如nginx可代理前后端,与前端客户端tcp连接,与后端服务器建立 tcp连接。
支持7层代理的软件:
- Nginx:基于http协议(nginx七层是通过proxy_pass)
- Haproxy:七层代理,会话保持、标记、路径转移等
4、区别
四层的负载均衡,就是通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。
七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比 如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。
- 分层位置:四层负载均衡在传输层及以下,七层负载均衡在应用层及以下。
- 性能 :四层负载均衡架构无需解析报文消息内容,在网络吞吐量与处理能力上较高:七层可支持解析应用 层报文消息内容,识别URL、Cookie、HTTP header等信息。
- 原理 :四层负载均衡是基于ip+port;七层是基于虚拟的URL或主机IP等。
- 功能类比:四层负载均衡类似于路由器;七层类似于代理服务器。 5.安全性:四层负载均衡无法识别DDoS攻击;七层可防御SYN Cookie/Flood攻击。
二、定义
- HAProxy是法国开发者威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源软件,是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器 支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计
- HAProxy 七层代理是指在 OSI 模型的第七层(应用层)进行代理操作。 在七层代理中,HAProxy 不仅能够根据 IP 地址和端口进行流量分发,还能够理解应用层协议(如 HTTP、HTTPS 等)的内容。 这意味着它可以基于诸如请求的 URL、HTTP 方法、HTTP 头部信息等更详细的应用层数据来做出决策和进行流量的分配。
三、基本配置
1、global---全局配置段
- 进程及安全配置相关的参数
- 性能调整相关参数
- Debug参数
global
log 127.0.0.1 local3
log 127.0.0.1 local1 notice
#log loghost local0 info
ulimit-n 82000
maxconn 20480
chroot /usr/local/haproxy
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/run/haproxy.pid
#debug
#quiet
解释一下:
- log:全局的日志配置,local0是日志输出设置,info表示日志级别。
- maxconn:设定每个haproxy进程可接受的最大并发连接数。
- chroot:修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作。
- daemon:让 haproxy 以后台模式运行,不占用终端的输入输出。
- nbproc:设置运行的进程数量。
- pidfile:用于记录运行中的 haproxy 进程的 ID,方便其他程序或脚本对其进行管理和监控。
- ulimit-n:设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项。
2、proxies---代理配置段
参数说明:
- defaults:为frontend, backend, listen提供默认配置
- frontend:前端,相当于nginx中的server {}
- backend:后端,相当于nginx中的upstream {}
- listen:同时拥有前端和后端配置,配置简单,生产推荐使用
(1)defaults
defaults
log global
mode http
maxconn 50000
option httplog
option httpclose
option dontlognull
option forwardfor
retries 3
stats refresh 30
option abortonclose
balance roundrobin
#balance source
#contimeout 5000
#clitimeout 50000
#srvtimeout 50000
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
解释一下:
- defaults:表示以下的配置是默认的全局配置。
- log global:引入名为“global”定义的日志格式,用于记录相关的日志信息。
- mode http:指定所处理的类别为 7 层代理的 HTTP 模式。
- maxconn 50000:设置最大的连接数量为 50000 个。
- option httplog:表示日志的类别为 HTTP 日志格式,用于记录 HTTP 相关的日志。
- option httpclose:每次 HTTP 请求完毕后,主动关闭 HTTP 通道,释放资源。
- option dontlognull:不记录健康检查的日志信息,避免产生不必要的日志记录。
- option forwardfor:如果后端服务器需要获取客户端的真实 IP 地址,通过这个参数可以从 HTTP 头中获取。
- retries 3:如果连接失败,最多尝试重新连接 3 次,超过 3 次则认为服务器不可用。
- stats refresh 30:设置统计页面的刷新时间间隔为 30 秒。
- option abortonclose:当服务器负载很高时,自动结束当前队列中处理时间较长的连接,以释放资源。
- balance roundrobin:设置默认的负载均衡方式为轮询方式,即依次将请求分配到不同的服务器。 timeout http-request 10s:默认的 HTTP 请求超时时间为 10 秒,如果在 10 秒内未完成请求,则视为超时。
- timeout queue 1m:默认的队列超时时间为 1 分钟。
- timeout connect 10s:默认的连接超时时间为 10 秒。
- timeout client 1m:默认的客户端超时时间为 1 分钟。
- timeout server 1m:默认的服务器超时时间为 1 分钟。
- timeout http-keep-alive 10s:默认的 HTTP 持久连接超时时间为 10 秒。
- timeout check 10s:设置超时检查的超时时间为 10 秒。
(2)frontend
frontend http_80_in
bind 0.0.0.0:80
mode http
log global
option httplog
option httpclose
option forwardfor
default_backend wwwpool
解释一下:
- frontend http_80_in:定义一个名为http_80_in的frontend。
- bind 0.0.0.0:80:表示将 HAProxy 服务绑定到所有可用的网络接口(0.0.0.0)的 80 端口上。这样,客户端可以通过任何网络接口连接到这个端口来发送请求。
- mode http:指定了工作模式为 HTTP 的 7 层模式。在这种模式下,HAProxy 可以理解和处理 HTTP 协议的相关信息,例如请求头、响应头。
- log global:应用全局的日志设置,意味着使用在全局配置中定义的日志规则来记录与这个前端相关的操作和事件。
- option httplog:启用了 HTTP 相关的日志记录,以便更详细地记录 HTTP 请求和响应的信息。 option httpclose:每次处理完请求后主动关闭 HTTP 通道。这是因为 HAProxy 不支持 HTTP 的 keep-alive 模式,为了避免资源占用和潜在的问题,选择在请求完成后关闭连接。
- option forwardfor:如果后端服务器需要获取客户端的真实 IP 地址,配置此参数可以从 HTTP 头中提取客户端的真实 IP 信息。
- default_backend wwwpool:设置了默认情况下,接收到的请求将被转发到名为 `wwwpool` 的后端服务池进行处理。 例如,如果有多个客户端向 80 端口发送 HTTP 请求,HAProxy 会根据上述配置来处理这些请求。如果后端服务器需要知道是哪个客户端发起的请求,通过 `option forwardfor` 就能获取到真实的客户端 IP 地址。而所有没有特别指定后端的请求,都会被默认转发到 `wwwpool` 这个后端服务池去处理。
(3)backend
backend wwwpool
mode http
option redispatch
option abortonclose
balance source
cookie SERVERID
option httpchk GET /test.html
server web1 10.1.1.2:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3 maxconn 8
解释一下:
- backend wwwpool:定义了一个“wwwpool”的服务器组。
- mode http:指定使用 HTTP 的 7 层模式进行负载均衡。这意味着不仅会考虑 IP 和端口,还会分析 HTTP 请求的内容(如 URL、请求头)来做出负载均衡决策。
- option redispatch:重分发选项,通常用于在某些情况下重新分配请求到其他服务器。
- option abortonclose:当连接关闭时采取特定的动作,可能与处理异常关闭的连接相关。 *
- balance source:表示使用源哈希算法进行负载均衡。这意味着根据客户端的源 IP 地址来决定将请求分配到哪个后端服务器,相同源 IP 的请求通常会被发送到同一台服务器。
- cookie SERVERID:允许在 cookie 中插入“SERVERID”。这有助于跟踪和识别与特定服务器的会话关联。
- option httpchk GET /test.htm:心跳检测,通过发送 GET 请求到“/test.html”路径来检查后端服务器的健康状况。
- server web1 10.1.1.2:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3 maxconn 8:
- -- “server web1”定义了服务器的名称为“web1”。
- -- “10.1.1.2:80”是服务器的 IP 地址和端口。
- -- “cookie 2”可能表示与该服务器相关的特定 cookie 设置。
- -- “weight 3”为服务器设置权重为 3,权重越大,分配到的请求相对越多。
- -- “check inter 2000”表示检查的间隔为 2000 毫秒。
- -- “rise 2”表示服务器被认为正常的连续成功检查次数为 2 次。
- -- “fall 3”表示服务器被认为故障的连续失败检查次数为 3 次。
- -- “maxconn 8”表示该服务器的最大并发连接数为 8。
(4)listen
listen admin_status
bind 0.0.0.0:8888
mode http
log 127.0.0.1 local3 err
stats refresh 5s
stats uri /admin?stats
stats realm itnihao\ welcome
stats auth admin:admin
stats auth admin1:admin1
stats hide-version
stats admin if TRUE
解释一下:
- listen admin_status:Frontend和Backend的组合体,监控组的名称。
- bind 0.0.0.0:8888:指定监听的 IP 地址和端口。`0.0.0.0`表示监听所有可用的网络接口,`8888`是端口号。
- mode http:表示采用 HTTP 的七层模式进行处理。在这种模式下,HAProxy 可以更深入地理解和处理 HTTP 协议的相关内容。
- log 127.0.0.1 local3 err:指定将错误日志发送到 `127.0.0.1` 这个本地地址,并使用 `local3` 这个日志设施,记录错误级别的信息。
- stats refresh 5s:设置监控页面每隔 5 秒钟自动刷新一次,以提供实时的状态信息。
- stats uri /admin?stats:定义了访问监控页面的 URL 路径为 `/admin?stats` 。
- stats realm itnihao\ welcome:这是监控页面的提示信息,可能在用户访问监控页面时显示。 stats auth admin:admin 和 stats auth admin1:admin1:为监控页面设置了用户认证信息,分别为 `admin` 用户对应密码 `admin` ,`admin1` 用户对应密码 `admin1` 。
- stats hide-version:用于隐藏统计页面上的 HAProxy 版本信息,可能是出于安全或其他考虑。 stats admin if TRUE:用于手工启用或禁用后端服务器,这是在 HAProxy 1.4.9 及以后版本可用的功能。如果设置为 `TRUE` ,则表示启用相关的监控或管理操作。
3、haproxy负载均衡
环境:
主机 | IP | 硬件配置 |
haproxy | 172.25.254.100 | NAT网卡 |
server1 | 172.25.254.10 | NAT网卡 |
serveer2 | 172.25.254.20 | NAT网卡 |
haproxy配置如下:
[root@haproxy ~]# dnf install haproxy -y
[root@haproxy ~]# rpm -qc haproxy
/etc/haproxy/haproxy.cfg
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
修改内容如下:
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend webcluster
bind *:80
mode http
use_backend webcluster-hostbackend webcluster-host
balance roundrobin
server web1 172.25.254.10:80
server web2 172.25.254.20:80listen webcluster
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80
server web2 172.25.254.20:80
重启
[root@haproxy ~]# systemctl restart haproxy.service
测试
[root@haproxy ~]# for i in {1..10}
> do
> curl 172.25.254.100
> done
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20
日志重定向操作:
[root@haproxy ~]# vim /etc/rsyslog.conf
module(load="imudp") # needs to be done just once
input(type="imudp" port="514")# Save boot messages also to boot.log
local7.* /var/log/boot.log
local2.* /var/log/haproxy.log
重启:
[root@haproxy ~]# systemctl restart haproxy.service
server1配置:
[root@server1 ~]# dnf install nginx -y
[root@server1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index.html
[root@server1 ~]# systemctl enable --now nginx.service
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
server2配置:
[root@server2 ~]# dnf install -y nginx
[root@server2 ~]# echo webserver2 - 172.25.254.20 > /usr/share/nginx/html/index.html
[root@server2 ~]# systemctl enable --now nginx.service
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
4、haproxy热处理
(1)socat
#编辑配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
global
stats socket /var/lib/haproxy/stats mode 600 level admin
#查看haproxy的状态
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats
Name: HAProxy
Version: 2.4.22-f8e3218
Release_date: 2023/02/14
Nbthread: 2
Nbproc: 1
Process_num: 1
Pid: 2104
Uptime: 0d 0h00m26s
Uptime_sec: 26
……
#查看集群状态
[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats
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 srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port
2 webcluster 1 web1 192.168.0.10 2 0 1 1 80 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 2 web2 192.168.0.20 2 0 1 1 80 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 3 web_sorry 192.168.0.100 2 0 1 1 80 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
5 static 1 static 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 4331 - 0 0 - - 0
6 app 1 app1 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 5001 - 0 0 - - 0
6 app 2 app2 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 5002 - 0 0 - - 0
6 app 3 app3 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 5003 - 0 0 - - 0
6 app 4 app4 127.0.0.1 0 0 1 1 78 8 2 0 6 0 0 0 - 5004 - 0 0 - - 0
#查看集群的权重
[root@haproxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats
1 (initial 1)
@临时修改权重
[root@haproxy ~]# echo "set weight webcluster/web1 2" | socat stdio /var/lib/haproxy/stats
[root@haproxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats
2 (initial 1)
#下线后端服务器
[root@haproxy ~]# echo "disable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
#上线后端服务器
[root@haproxy ~]# echo "enable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1
stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2
nbproc 2
cpu-map 1 0
cpu-map 2 1
四、haproxy的调度算法
1、静态调度算法
(1)static-rr(基于权重的轮询调度 )
在listen或backend区域配置
balance static-rr
不⽀持权重的运⾏时调整及后端服务器慢启动,其后端主机数量没有限制。weight默认为1。
listen web_host
bind 192.168.7.101:80,:8801-8810,192.168.7.101:9001-9010
mode http/tcp
log global
balance static-rr
server web1 192.168.7.103:80 weight 1 check inter 3000 fall 2 rise 5
server web2 192.168.7.104:80 weight 2 check inter 3000 fall 2 rise 5
(2)first
配置位置同上
- 根据服务器在列表中的位置,自上而下进行调度
- 其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
- 其会忽略服务器的权重设置
- 不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
listen web_host
bind 192.168.7.101:80,:8801-8810,192.168.7.101:9001-9010
mode http/tcp
log global
balance first
server web1 192.168.7.103:80 maxconn 2 weight 1 check inter 3000 fall 2 rise 5
server web2 192.168.7.104:80 weight 1 check inter 3000 fall 2 rise 5
2、动态调度算法
(1)roundrobin
配置位置依然同上
- 基于后端服务器状态进行调度适当调整
- 新请求将优先调度至当前负载较低的服务器
- 权重可以在haproxy运行时动态调整无需重启
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen server_80bind 172.25.254.100:80mode httpbalance roundrobinserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
动态调度权重
[root@haproxy ~]# echo "set weight server_80/server1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
(2)leastconn
配置位置依旧同上
- eastconn加权的最少连接的动态
- 支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)
- 比较适合长连接的场景使用,比如:MySQL等场景
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen server_80
bind 172.25.254.100:80mode httpbalance leastconnserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
3、其他算法
(1)source
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80bind 172.25.254.100:80mode httpbalance sourceserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
测试
[root@node5 ~]# for N in {1..6}; do curl 172.25.254.100; done
a.map-base取模法
- 对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请 求转发至对应的后端服务器。
- 此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度
- 缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变
b.一致性hash
- 一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动hash(o)mod n
- 该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动
- 后端服务器哈希环点keyA=hash(后端服务器虚拟ip)%(2^32)
- 客户机哈希环点key1=hash(client_ip)%(2^32) 得到的值在[0---4294967295]之间,
- 将keyA和key1都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器
hash环偏斜问题解决方法:
一致性hash示意图:
一致性hash配置示例:
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80mode httpbalance sourcehash-type consistentserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
(2)uri
- 基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后根据最终结果将请求转发到后端指定服务器
- 适用于后端是缓存服务器场景
- 默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash
a.配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80mode httpbalance uriserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
b.一致性hash配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80mode httpbalance urihash-type consistentserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
c.访问测试
[root@rs1 ~]# echo RS1 192.168.0.101 index1 > /var/www/html/index1.html
[root@rs1 ~]# echo RS1 192.168.0.101 index2 > /var/www/html/index2.html
[root@rs1 ~]# echo RS1 192.168.0.101 index3 > /var/www/html/index3.html
[root@rs2 ~]# echo RS1 192.168.0.102 index1 > /var/www/html/index1.html
[root@rs2 ~]# echo RS1 192.168.0.102 index2 > /var/www/html/index2.html
[root@rs2 ~]# echo RS1 192.168.0.102 index3 > /var/www/html/index3.html
[root@node10 ~]# curl 172.25.254.100/index.html
RS2 server - 192.168.0.102
[root@node10 ~]# curl 172.25.254.100/index1.html
RS1 192.168.0.101 index1
[root@node10 ~]# curl 172.25.254.100/index2.html
RS1 192.168.0.102 index2
[root@node10 ~]# curl 172.25.254.100/index3.html
(3)hdr
- 针对用户每个http头部(header)请求中的指定信息做hash
- 此处由 name 指定的http首部将会被取出并做hash计算
- 然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度
a.取模法配置示例:
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80bind 172.25.254.100:80mode httpbalance uriserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
b.一致性hash配置示例:
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80mode httpbalance urihash-type consistentserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
测试访问:
[root@node10 ~]# curl -v 172.25.254.100
[root@node10 ~]# curl -vA "firefox" 172.25.254.100[root@node10 ~]# curl -vA "sougou" 172.25.254.100
(4)url_param
a.配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80bind 172.25.254.100:80mode httpbalance url_param name,userid # 支持对多个 url_param hashserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
b.一致性hash配置性示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80bind 172.25.254.100:80mode httpbalance url_param name,userid # 支持对多个 url_param hashhash-type consistentserver server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
测试访问
[root@node10 ~]# curl 172.25.254.100/index3.html?name=leeRS1 192.168.0.101 index3[root@node10 ~]# curl 172.25.254.100/index3.html?name=leeRS1 192.168.0.101 index3[root@node10 ~]# curl 172.25.254.100/index3.html?name=testRS1 192.168.0.102 index3[root@node10 ~]# curl 172.25.254.100/index3.html?name=testRS1 192.168.0.101 index3
(5)算法总结
a.静态
b.动态
c.以下静态和动态取决于hash_type是否consistent
(6)各算法使用场景
first # 使用较少static-rr # 做了 session 共享的 web 集群roundrobinleastconn # 数据库source
a.基于客户端公网IP的会话保持
Uri--------------->http # 缓存服务器, CDN 服务商,蓝汛、百度、阿里云、腾讯url_param--------->http # 可以实现 session 保持hdr # 基于客户端请求报文头部做下一步处理
五、haproxy的高级功能配置
1、基于cookie的会话保持
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen web_host
bind 172.25.254.100:80
mode http
log global
balance roundrobin
cookie SERVER-COOKIE insert indirect nocache
server web1 10.0.0.201:80 cookie web1 check inter 3000 fall 3 rise 5
server web2 10.0.0.202:80 cookie web2 check inter 3000 fall 3 rise 5
测试
[root@node5 ~]# curl --cookie "SERVER-COOKIE=web1" http://172.25.254.100/index.html
server1 10.0.0.201
[root@node5 ~]# curl --cookie "SERVER-COOKIE=web2" http://172.25.254.100/index.html
server2 10.0.0.202
2、haproxy状态页
启用状态页:
stats enable #基于默认的参数启用stats page
stats hide-version #隐藏版本
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中的管理功能
配置状态页:
listen stats
bind :172.25.254.100:9999
stats enable
#stats hide-version
stats uri /haproxy-status
stats realm HAPorxy\ Stats\ Page
stats auth haadmin:123456
stats auth admin:123456
#stats refresh 30s
#stats admin if TRUE
测试
backend server信息
六、IP透传
1、四层IP透传
[root@haproxy ~]# vim /etc/nginx/nginx.conf
修改配置文件
listen webserver_80bind 172.25.254.100:80mode tcpbalance roundrobinserver server1 192.168.0.101:80 send-proxy weight 1 check inter 3s fall 3rise 5
查看日志内容
[root@haproxy ~]# tail -n 3 /var/log/nginx/access.log
2、七层IP透传
(1)haproxy配置
修改配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen server_80option forwardforbind 172.25.254.100:80mode httpbalance roundrobinserver server1 192.168.0.101:80 send-proxy weight 1 check inter 3s fall 3rise 5server server1 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
(2)web服务器日志格式配置
修改配置文件
[root@haproxy ~]# vim /etc/nginx/nginx.conf
重启
systemctl restart nginx.service
查看日志
tail /var/log/nginx/access.log
七、ACL
1、配置选项
acl <aclname> <criterion> [flags] [operator] [<value>]acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
2、ACL-criterion
定义ACL匹配规范
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息
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模糊匹配
dst 目标IP
dst_port 目标PORT
src 源IP
src_port 源PORT
示例:
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.magedu.com
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn
path_beg 请求的URL开头,如/static、/images、/img、/css
path_end 请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg
有些功能是类似的,比如以下几个都是匹配用户请求报文中host的开头是不是www:
acl short_form hdr_beg(host) www.
acl alternate1 hdr_beg(host) -m beg www.
acl alternate2 hdr_dom(host) -m beg www.
acl alternate3 hdr(host) -m beg www.
3、ACL-flags
匹配模式:
-i | 不区分大小写 |
-m | 使用指定的pattern匹配方法 |
-n | 不做DNS解析 |
-u | 禁止acl重名,否则多个同名ACL匹配或关系 |
4、ACL-operator
ACL 操作符
(1)整数比较:eq、ge、gt、le、lt
(2)字符比较:
- 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进行匹配
5、ACL-value
value的类型
- Boolean #布尔值
- integer or integer range #整数或整数范围,比如用于匹配端口范围
- IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
- string--> www.magedu.com
- exact –精确比较
- substring—子串
- suffix-后缀比较
- prefix-前缀比较
- subdir-路径, /wp-includes/js/jquery/jquery.js
- domain-域名,www.magedu.com
- regular expression #正则表达式
- hex block #16进制
6、调用方式
- 与:隐式(默认)使用
- 或:使用“or” 或 “||”表示
- 否定:使用“!“ 表示
示例:
if valid_src valid_port #与关系,A和B都要满足为true
if invalid_src || invalid_port #或,A或者B满足一个为true
if ! invalid_src #非,取反,A和B哪个也不满足为true
7、ACL的实例
修改配置文件
[root@haproxy conf.d]# vim /etc/haproxy/haproxy.cfg
重启
[root@haproxy conf.d]# systemctl restart haproxy.service
测试
curl www.test.com
curl www.timinglee.org
八、自定义错误页面
1、haproxy默认使用的错误页面
[root@haproxy ~]# rpm -ql haproxy24z-2.4.27-1.el7.zenetys.x86_64 | grep -E http$
/usr/share/haproxy/400.http
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http
2、自定义的错误页面文件
errorfile <code> <file>
<code> #HTTP status code. 支持 200, 400, 403, 405, 408, 425, 429, 500, 502 , 503,504
<file> # 包含完整 HTTP 响应头的错误页文件的绝对路径。 建议后缀 ".http" ,以和一般的 html 文件相区分
示例
errorfile 503 /haproxy/errorpages/503page.http
3、http重定向错误页面
errorloc <code> <url>
示例:
errorloc 503 https://www.baidu.com
自定义错误文件
[root@haproxy ~]# mkdir /etc/haproxy/errorpage -p
[root@haproxy ~]# vim /etc/haproxy/errorpage/503.http
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
[root@haproxy ~]# systemctl restart haproxy.service
[root@server ~]# systemctl stop httpd
[root@server2 ~]# systemctl stop nginx.service
[root@server2 ~]# systemctl restart nginx.service
[root@server2 ~]# systemctl status nginx.service
九、四层负载示例
在后台服务器安装和配置mariadb服务
[root@haproxy ~]#yum install mariadb-server -y
[root@server ~]# yum install mariadb-server -y
[root@server2 ~]# yum install mariadb-server -y
[root@server ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@server ~]# systemctl start mariadb.service
[root@server2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@server2 ~]# systemctl start mariadb.service
十、haproxy的https
证书制作
[root@haproxy ~]# mkdir -p /etc/haproxy/certs
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt
[root@haproxy ~]# ls /etc/haproxy/certs/ timinglee.org.crt timinglee.org.key
[root@haproxy ~]# cat /etc/haproxy/certs/timinglee.org.key /etc/haproxy/certs/timinglee.org.crt > /etc/haproxy/certs/timinglee.pem
[root@haproxy ~]# cat /etc/haproxy/certs/timinglee.pem
http配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
[root@haproxy ~]# systemctl restart haproxy.service
最后测试即可
至此,以上就是haproxy七层代理的全部内容了