基本介绍
http://t.csdnimg.cn/Z64QVhttp://t.csdnimg.cn/Z64QV
实验环境
功能 | IP |
客户端 | 172.25.254.233 |
haproxy | eth0:172.25.254.100 eth1:192.168.0.10 |
rs1 | eth0:192.168.0.101 |
rs2 | eth0:192.168.0.102 |
安装haproxy
yum install haproxy -y
多进程和多线程
vim /etc/haproxy/haproxy.cfg
多进程
查看多进程信息
多线程
查看多线程
haproxy的状态界面
Proxies配置-listen 简化配置
socat 工具
查看haproxy状态
#查看集群权重
[root@haproxy ~]# echo get weight webcluster/web1 | socat stdio
/var/lib/haproxy/stats
2 (initial 2)
[root@haproxy ~]# echo get weight webcluster/web2 | socat stdio
/var/lib/haproxy/stats
1 (initial 1)
#设置权重
[root@haproxy ~]# echo "set weight webcluster/web1 1 " | socat stdio
/var/lib/haproxy/stats
[root@haproxy ~]# echo "set weight webcluster/web1 2 " | socat stdio
/var/lib/haproxy/stats
#下线后端服务器
[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
针对多进程处理方法
在配置文件中修改增加以下内容
stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2nbproc 2cpu-map 1 0cpu-map 2 1
静态算法
static-rr:基于权重的轮询调度
不支持运行时利用 socat 进行权重的动态调整 ( 只支持 0 和 1, 不支持其它值 )不支持端服务器慢启动其后端主机数量没有限制,相当于 LVS 中的 wrr
示例:
vim /etc/haproxy/haproxy.cfgstats 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
[root@haproxy ~]# ll /var/lib/haproxy/
总用量 0
srw------- 1 root root 0 8月 8 13:43 stats
srw------- 1 root root 0 8月 8 13:46 stats1
srw------- 1 root root 0 8月 8 13:46 stats2
first
根据服务器在列表中的位置,自上而下进行调度其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务其会忽略服务器的权重设置不支持用 socat 进行动态修改权重 , 可以设置 0 和 1, 可以设置其它值但无效
示例:
vim /etc/haproxy/haproxy.cfglisten webserver_80
bind 172.25.254.100:80
mode http
balance first
server webserver1 192.168.0.101:80 maxconn 3 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 check inter 3s fall 3 rise 5
测试效果:
#在两台主机上分别执行此循环,可以观察是否102被调度到
while true;do curl 172.25.254.100 ; sleep 0.1;done
动态算法
基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器权重可以在 haproxy 运行时动态调整无需重启
roundrobin
1. 基于权重的轮询动态调度算法,2. 支持权重的运行时调整,不同于 lvs 中的 rr 轮训模式,3. HAProxy 中的 roundrobin 支持慢启动 ( 新加的服务器会逐渐增加转发数 ) ,4. 其每个后端 backend 中最多支持 4095 个 real server ,5. 支持对 real server 权重动态调整,6. roundrobin 为默认调度算法 , 此算法使用广泛
示例:
vim /etc/haproxy/haproxy.cfglisten webserver_80
bind 172.25.254.100:80
mode http
balance roundrobin
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
动态调整权重
echo "set weight webserver_80/webserver1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
leastconn
leastconn 加权的最少连接的动态支持权重的运行时调整和慢启动,即 : 根据当前连接最少的后端服务器而非权重进行优先调度 ( 新客户端连接 )比较适合长连接的场景使用,比如: MySQL 等场景。
示例:
vim /etc/haproxy/haproxy.cfglisten webserver_80
bind 172.25.254.100:80
mode http
balance leastconn
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
其他算法
source
源地址 hash ,基于用户源地址 hash 并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端 web 服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过 hash-type 支持的选项更改这个算法一般是在不插入 Cookie 的 TCP模式下使用,也可给拒绝会话 cookie 的客户提供最好的会话粘性,适用于 session 会话保持但不支持cookie 和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性 hash
示例:
vim /etc/haproxy/haproxy.cfglisten webserver_80
bind 172.25.254.100:80
mode http
balance source
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
测试:
[root@node10 ~]# for N in {1..6}; do curl 172.25.254.100; done
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
如果访问客户端时一个家庭,那么所有的家庭的访问流量都会被定向到一台服务器,这时 source 算法的缺陷
map-base 取模法
map-based :取模法,对 source 地址进行 hash 计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变hash-type 指定的默值为此算法
示例:
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
bind 172.25.254.100:80
mode http
balance source
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
...上面内容省略...
#不支持动态调整权重值
[root@haproxy ~]# echo "set weight webserver_80/webserver1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
#只能动态上线和下线
[root@haproxy ~]# echo "set weight webserver_80/webserver1 0" | socat stdio
/var/lib/haproxy/haproxy.sock
[root@haproxy ~]# echo "get weight webserver_80/webserver1" | socat stdio
/var/lib/haproxy/haproxy.sock
0 (initial 1)
一致性 hash
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动 hash ( o )mod n该 hash 算法是动态的,支持使用 socat 等工具进行在线权重调整,支持慢启动
算法:
1 、后端服务器哈希环点 keyA=hash( 后端服务器虚拟 ip)%(2^32)2 、客户机哈希环点 key1=hash(client_ip)%(2^32) 得到的值在 [0---4294967295] 之间,3 、将 keyA 和 key1 都放在 hash 环上,将用户请求调度到离 key1 最近的 keyA 对应的后端服务器
hash环偏斜问题
增加虚拟服务器 IP 数量,比如:一个后端服务器根据权重为 1 生成 1000 个虚拟 IP ,再 hash 。而后端服务器权重为 2 则生成 2000 的虚拟 IP ,再 bash, 最终在 hash 环上生成 3000 个节点,从而解决 hash 环偏斜问题
示例:
listen webserver_80
bind 172.25.254.100:80
mode http
balance source
hash-type consistent
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
uri
基于对用户请求的 URI 的左半部分或整个 uri 做 hash ,再将 hash 结果对总权重进行取模后根据最终结果将请求转发到后端指定服务器适用于后端是缓存服务器场景默认是静态算法,也可以通过 hash-type 指定 map-based 和 consistent ,来定义使用取模法还是一致性 hash
示例:
listen webserver_80
bind 172.25.254.100:80
mode http
balance uri
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
uri 一致性hash配置示例
listen webserver_80
bind 172.25.254.100:80
mode http
balance uri
hash-type consistent
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
访问测试
[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
基于cookie的会话保持
配置:
listen webserver_80bind 172.25.254.100:80option forwardformode httpbalance roundrobincookie WEBCOOKIE insert nocache indirectserver webserver1 192.168.0.101:80 cookie web1 weight 1 check inter 3s fall 3 rise 5server webserver2 192.168.0.102:80 cookie web2 weight 1 check inter 3s fall 3 rise 5
测试:
指导cookie访问
haproxy状态页配置
状态页配置项
stats enable # 基于默认的参数启用 stats pagestats hide-version # 将状态页中 haproxy 版本隐藏stats refresh <delay> # 设定自动刷新时间间隔,默认不自动刷新stats uri <prefix> # 自定义 stats page uri ,默认值: /haproxy?statsstats auth <user>:<passwd> # 认证时的账号和密码,可定义多个用户 , 每行指定一个用户# 默认: no authenticationstats admin { if | unless } <cond> # 启用 stats page 中的管理功能
IP透传
web 服务器中需要记录客户端的真实 IP 地址,用于做访问统计、安全防护、行为分析、区域排行等场景。
四层IP透传
[haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
bind 172.25.254.100:80
mode tcp
balance roundrobin
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
#正常的nginx配置
[root@rs1 ~]# vim /etc/nginx/nginx.conf
。。。内容省略。。。
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request"'
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
。。。内容省略。。。
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
。。。内容省略。。。
}
}
#在访问haproxy后查看nginx日志
[root@rs1 ~]# tail -n 3 /var/log/nginx/access.log
192.168.0.10 - - [10/Jul/2024:15:21:00 +0800] "GET / HTTP/1.1"200 18 "-"
"curl/7.29.0" "-"192.168.0.10 - - [10/Jul/2024:15:26:11 +0800] "GET /
HTTP/1.1"200 18 "-" "curl/7.29.0" "-"
在此日志中是无法看到真实访问源地址的
开启四层透传
[root@rs1 ~]# vim /etc/nginx/nginx.conf
。。。内容省略。。。
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request"'
5.3.3 七层IP透传
当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器
5.3.3.1 HAProxy配置
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For"首部,其值为前端客户端的地址;用于
向后端主发送真实的客户端IP
示例:
' "$proxy_protocol_addr"'
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
。。。内容省略。。。
server {
listen 80 proxy_protocol; #启用此项,将无法直接访问此网站,只能通过四层代理
访问
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
。。。内容省略。。。
}
}
#修改haproxy
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
bind 172.25.254.100:80
mode tcp
balance roundrobin
server webserver1 192.168.0.101:80 send-proxy weight 1 check inter 3s fall 3
rise 5
...上面内容省略...
#查看日志内容
[root@rs1 ~]# tail -n 3 /var/log/nginx/access.log
192.168.0.10 - - [10/Jul/2024:15:21:00 +0800] "GET / HTTP/1.1"200 18 "-"
"curl/7.29.0" "-"
192.168.0.10 - - [10/Jul/2024:15:26:11 +0800] "GET / HTTP/1.1"200 18 "-"
"curl/7.29.0" "-"
192.168.0.10 - - [10/Jul/2024:15:41:56 +0800] "GET / HTTP/1.1" "172.25.254.10"200
18 "-" "curl/7.29.0"
七层 IP 透传
当 haproxy 工作在七层的时候,也可以透传客户端真实 IP 至后端服务器
示例:
#修改haproxy
[haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
option forwardfor
bind 172.25.254.100:80
mode http
balance roundrobin
server webserver1 192.168.0.101:80 send-proxy weight 1 check inter 3s fall 3 rise 5
server webserver1 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
ACL配置选项
# 用 acl 来定义或声明一个 aclacl <aclname> <criterion> [flags] [operator] [<value>]acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
示例:
[haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
frontend testacl
bind :80
mode http
########### ACL settings #######################
acl web_host hdr_dom(host) www.timinglee.org
########### host ###########################
use_backend timinglee_host if web_host
########### default server ###################
default_backend default_webserver
backend timinglee_host
mode http
server web1 192.168.0.101:80 check weight 1 inter 3s fall 3 rise 5
server web2 192.168.0.102:80 check weight 1 inter 3s fall 3 rise 5
backend default_webserver
mode http
server web1 172.25.254.10:80 check weight 1 inter 3s fall 3 rise 5
测试结果
#在浏览器所在主机中做地址解析
[root@node10 html]# vim /etc/hosts
172.25.254.100 www.timinglee.org
#测试结果
[root@node10 html]# curl www.timinglee.org
RS1 192.168.0.101
[root@node10 html]# curl www.timinglee.org
RS2 server - 192.168.0.102
[root@node10 html]# curl 172.25.254.100
default web server node10
自定义HAProxy 错误界面
基于自定义错误页面文件
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
defaults
测试:
5.5.2 基于http重定向错误页面
范例:
mode http
...内容省略...
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 1000000
errorfile 503 /haproxy/errorpages/503page.http
[root@haproxy ~]# mkdir /haproxy/errorpages/ -p
[root@haproxy ~]# cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http
[root@haproxy ~]# vim /haproxy/errorpages/503page.http
HTTP/1.0 503 Service Unavailable^M
Cache-Control: no-cache^M
Connection: close^M
Content-Type: text/html;charset=UTF-8^M
^M
<html><body><h1>什么动物生气最安静</h1>
大猩猩!!
</body></html>
基于 http 重定向错误页面
[haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
defaults
mode http
...内容省略...
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
5.6 HAProxy 四层负载
针对除HTTP以外的TCP协议应用服务访问的应用场景
四层负载示例
注意:如果使用frontend和backend,一定在 frontend 和 backend 段中都指定mode tcp
范例:对 MySQL 服务实现四层负载
maxconn 1000000
errorloc 503 https://www.baidu.com
#浏览器访问172.25.254.100 自动跳转到百度
HAProxy https 实现
haproxy 可以实现 https 的证书安全 , 从用户到 haproxy 为 https, 从 haproxy 到后端服务器用 http 通信但基于性能考虑 , 生产中证书都是在后端服务器比如 nginx 上实现
证书制作
[haproxy ~]# mkdir /etc/haproxy/certs/
[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
配置:
[haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webserver
bind *:80
redirect scheme https if !{ ssl_fc }
mode http
use_backend webcluster
frontend webserver-https
bind *:443 ssl crt /etc/haproxy/timinglee.org.pem
mode http
use_backend webcluster
backend webcluster
mode http
balance roundrobin
server web1 172.25.254.200:80 check inter 3s fall 3 rise 5
server web2 172.25.254.201:80 check inter 3s fall 3 rise 5