haproxy七层代理

目录

一、haproxy简介

二、haproxy实验

1.环境部署

2.haproxy的基本部署方法及负载均衡的实现

2.1安装软件

2.2haproxy的基本配置

3.haproxy的全局配置参数及日志分离

3.1多线程设定

3.2自定义日志

4.haproxy-proxies中的常用配置参数

4.1设置backup --- sorryserver的端口

4.2访问重定向

5.haproxy热更新方法

5.1socat

6.haproxy中的算法

6.1静态算法

6.1.1static-rr:基于权重的轮询调度

6.1.2 first

6.2动态算法

6.2.1roundrobin

6.2.2 leastconn

6.3其他算法

6.3.1source

6.3.1.1 map-base 取模法

6.3.1.2 一致性hash

6.3.2 uri

6.3.2.1 uri 取模法配置示例

6.3.3 url_param

6.3.3.1 url_param取模法配置示例

6.3.4 hdr

6.3.4.1 hdr取模法配置示例

6.3.6 算法总结

6.3.7 各算法使用场景

三.高级功能及配置

3.1基于cookie的会话保持

3.1.1 配置选项

​编辑

3.2HAProxy状态页

3.2.1 状态页配置项

3.3 IP透传

3.3.2 四层IP透传

3.3.3 七层IP透传

3.4 ACL

基于源IP或子网调度访问

基于浏览器的访问控制

基于文件后缀名实现动静分离

 重定向错误文件

3.5 haproxy的四层负载

3.6 haproxy中https实现

3.6.1 证书制作


一、haproxy简介

HAProxy 是法国开发者 威利塔罗 (Willy Tarreau) 2000 年使用 C 语言开发的一个开源软件
是一款具备高并发 ( 万级以上 ) 、高性能的 TCP HTTP 负载均衡器
支持基于 cookie 的持久性,自动故障切换,支持正则表达式及 web 状态统计
企业版网站: https://www.haproxy.com
社区版网站: http://www.haproxy.org
github https://github.com/haprox
企业版本和社区版功能对比

二、haproxy实验

1.环境部署

haproxy192.168.5.100
webserver1192.168.5.10
webserver2192.168.5.20

2.haproxy的基本部署方法及负载均衡的实现

2.1安装软件
dnf install haproxy -y
2.2haproxy的基本配置

3.haproxy的全局配置参数及日志分离

3.1多线程设定

3.2自定义日志
vim /etc/rsyslog.conf

4.haproxy-proxies中的常用配置参数

4.1设置backup --- sorryserver的端口

disabled指定下线的后端服务器

4.2访问重定向

5.haproxy热更新方法

5.1socat

下载

dnf install socat -y
# 查看 haproxy 状态
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats

# 查看集群状态
[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats

# 查看集群权重
[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
针对多进程问题

6.haproxy中的算法

6.1静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度 等,且无法实时修改权重( 只能为 0 1, 不支持其它值 ) ,只能靠重启 HAProxy 生效。
6.1.1static-rr:基于权重的轮询调度

6.1.2 first
# 在两台主机上分别执行此循环,可以观察是否 102 被调度到
while true;do curl 172.25.254.100 ; sleep 0.1;done
6.2动态算法
6.2.1roundrobin

动态调整权重
[root@haproxy ~]# echo "set weight webserver_80/webserver1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
6.2.2 leastconn

6.3其他算法
6.3.1source

6.3.1.1 map-base 取模法

所谓取模运算,就是计算两个数相除之后的余数, 10%7=3, 7%4=3
map-based 算法:基于权重取模, hash(source_ip)% 所有后端服务器相加的总权重
比如当源 hash 值时 1111 1112 1113 ,三台服务器 a b c 的权重均为 1
abc 的调度标签分别会被设定为 0 1 2 1111%3=1 1112%3=2 1113%3=0
1111 ----- > nodeb
1112 ------> nodec
1113 ------> nodea
如果 a 下线后,权重数量发生变化
1111%2=1 1112%2=0 1113%2=1
1112 1113 被调度到的主机都发生变化,这样会导致会话丢失
# 不支持动态调整权重值
[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)
6.3.1.2 一致性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 环偏斜问题
hash 对象
Hash 对象到后端服务器的映射关系:
一致性 hash 示意图
后端服务器在线与离线的调度方式
一致性 hash 配置示例
6.3.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>
6.3.2.1 uri 取模法配置示例

6.3.3 url_param
url_param 对用户请求的 url 中的 params 部分中的一个参数 key 对应的 value 值作 hash 计算,并由服务器
总权重相除以后派发至某挑出的服务器 , 后端搜索同一个数据会被调度到同一个服务器,多用与电商
通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个 real server
如果无没 key ,将按 roundrobin 算法
# 假设:
url = http://www.timinglee.com/foo/bar/index.php?key=value
# 则:
host = "www.timinglee.com"
url_param = "key=value"
6.3.3.1 url_param取模法配置示例

6.3.4 hdr
针对用户每个 http 头部 (header) 请求中的指定信息做 hash
此处由 name 指定的 http 首部将会被取出并做 hash 计算,
然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
6.3.4.1 hdr取模法配置示例

6.3.6 算法总结
# 静态
static-rr--------->tcp/http
first------------->tcp/http
# 动态
roundrobin-------->tcp/http
leastconn--------->tcp/http
# 以下静态和动态取决于 hash_type 是否 consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
6.3.7 各算法使用场景
first # 使用较少
static-rr # 做了 session 共享的 web 集群
roundrobin
leastconn # 数据库
source
# 基于客户端公网 IP 的会话保持
Uri--------------->http # 缓存服务器, CDN 服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http # 可以实现 session 保持
hdr # 基于客户端请求报文头部做下一步处理

三.高级功能及配置

3.1基于cookie的会话保持
cookie value :为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址 hash调度算法对客户端的粒度更精准,但同时也加大了haproxy 负载,目前此模式使用较少, 已经被 session共享服务器代替
3.1.1 配置选项
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 的请求都发送到同一台后端服务器

3.2HAProxy状态页
3.2.1 状态页配置项
stats enable # 基于默认的参数启用 stats page
stats hide-version # 将状态页中 haproxy 版本隐藏
stats refresh <delay> # 设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> # 自定义 stats page uri ,默认值: /haproxy?stats
stats auth <user>:<passwd> # 认证时的账号和密码,可定义多个用户 , 每行指定一个用户
# 默认: no authentication
stats admin { if | unless } <cond> # 启用 stats page 中的管理功能
登录状态页
#pid 为当前 pid 号, process 为当前进程号, nbproc nbthread 为一共多少进程和每个进程多少个线程
pid = 27134 (process #1, nbproc = 1, nbthread = 1)
# 启动了多长时间
uptime = 0d 0h00m04s
# 系统资源限制:内存 / 最大打开文件数 /
system limits: memmax = unlimited; ulimit-n = 200029
# 最大 socket 连接数 / 单进程最大连接数 / 最大管道数 maxpipes
maxsock = 200029; maxconn = 100000; maxpipes = 0
# 当前连接数 / 当前管道数 / 当前连接速率
current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps
# 运行的任务 / 当前空闲率
Running tasks: 1/14; 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 或者 backup 服务器人为下线的
active or backup DOWN for maintenance (MAINT)
#active 或者 backup 被人为软下线 ( 人为将 weight 改成 0)
active or backup SOFT STOPPED for maintenance
backend server 信息
session rate( 每秒的连接会话信息 ):
Errors( 错误统计信息 )
cur: 每秒的当前会话数量 :
Req: 错误请求量
max: 每秒新的最大会话数量
conn: 错误链接量
limit: 每秒新的会话限制量
Resp: 错误响应量
sessions( 会话信息 ):
Warnings( 警告统计信息 )
cur: 当前会话量
Retr: 重新尝试次数
max: 最大会话量
Redis: 再次发送次数
limit: 限制会话量
Total: 总共会话量
Server(real server 信息 )
LBTot: 选中一台服务器所用的总时间
Status: 后端机的状态,包括 UP DOWN
Last :和服务器的持续连接时间
LastChk: 持续检查后端服务器的时间
Wght: 权重
Bytes( 流量统计 )
Act: 活动链接数量
In: 网络的字节输入总量
Bck: 备份的服务器数量
Out: 网络的字节输出总量
Chk: 心跳检测时间
Dwn: 后端服务器连接后都是 DOWN 的数量
Denied( 拒绝统计信息 )
Dwntme: 总的 downtime 时间
Req: 拒绝请求量
Thrtle:server 状态
Resp: 拒绝回复量
####
3.3 IP透传
3.3.2 四层IP透传

# 查看日志内容
[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"
3.3.3 七层IP透传

配置 web 服务器,记录负载均衡透传的客户端 IP 地址
#apache 配置:
LogFormat "%{X-Forwarded-For}i %a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%
{User-Agent}i\"" combined
#nginx 日志格式:
$proxy_add_x_forwarded_for: 包括客户端IP和中间经过的所有代理的IP
$http_x_forwarded_For: 只有客户端IP
log_format main '"$proxy_add_x_forwarded_for" - $remote_user [$time_local]
"$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_For';
#查看日志如下:
[root@rs1 ~]# tail -n 3 /var/log/nginx/access.log
"172.25.254.10, 192.168.0.10" 192.168.0.10 - - [10/Jul/2024:16:15:00 +0800] "GET
/ HTTP/1.1"200 18 "-" "curl/7.29.0" "172.25.254.10"
[root@rs2 ~]# tail -n 3 /etc/httpd/logs/access_log
172.25.254.10 192.168.0.10 - - [11/Jul/2024:00:15:00 +0800] "GET / HTTP/1.1" 200
27 "-" "curl/7.29.0
3.4 ACL

基于源IP或子网调度访问
示例:
vim/etc/haproxy/haproxy.cfg
 
frontend webcluster
    bind *:80
    mode http
    acl ctrl_ip src 172.25.254.1 172.25.254.20 192.168.0.0/24  -----符合条件的访问RS1
    use_backend webcluster-host if  ctrl_ip
    default_backend default-host
 
backend webcluster-host
    mode http
    server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
 
backend default-host
    mode http
    server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
测试:
[root@werserver2 ~]# curl 172.25.254.100
webserver1 - 172.25.254.10
 
[root@haproxy ~]# curl www.test.com
webserver2 - 172.25.254.20
[root@haproxy ~]# 
frontend webcluster
    bind *:80
    mode http
    acl ctrl_ip src 172.25.254.1 172.25.254.20 192.168.0.0/24
    http-request deny if ctrl_ip    ------ 符合条件的拒绝访问
    default_backend default-host
 
backend webcluster-host
    mode http
    server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
 
backend default-host
    mode http
    server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
测试:
[root@werserver2 ~]# curl 172.25.254.100
webserver1 - 172.25.254.10
[root@werserver2 ~]# curl 172.25.254.100
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
[root@werserver2 ~]# 
 
[root@haproxy ~]# curl www.test.com   ---- 默认走RS2,走的default
webserver2 - 172.25.254.20
基于浏览器的访问控制
示例:
vim/etc/haproxy/haproxy.cfg
 
frontend webcluster
    bind *:80
    mode http
    acl badwebrowers hdr_sub(User-Agent) -i wget
    http-request deny if badwebrowers
    default_backend default-host
 
backend webcluster-host
    mode http
    server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
 
backend default-host
    mode http
    server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
基于文件后缀名实现动静分离
RS主机上:
[root@webserver1 ~]# dnf install php -y
[root@webserver1 ~]# systemctl restart nginx.service 
[root@webserver1 ~]# 
[root@webserver1 ~]# vim /usr/share/nginx/html/index.php
<?php   
        phpinfo();
?>
 
查看是否能访问到php

自定义haproxy的错误界面

两台web服务都给他挂掉
[root@werserver1 ~]# systemctl stop nginx.service 
[root@werserver2 ~]# systemctl stop nginx.service
 
此时访问不到

 重定向错误文件

3.5 haproxy的四层负载

测试

3.6 haproxy中https实现
haproxy 可以实现 https 的证书安全 , 从用户到 haproxy https, haproxy 到后端服务器用 http 通信
但基于性能考虑 , 生产中证书都是在后端服务器比如 nginx 上实现
#配置HAProxy支持https协议,支持ssl会话;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
#指令 crt 后证书文件为PEM格式,需要同时包含证书和所有私钥
cat demo.key demo.crt > demo.pem
#把80端口的请求重向定443
bind *:80
redirect scheme https if !{ ssl_fc }
3.6.1 证书制作
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
3.6.2 https 配置示例
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
[root@客户端 ~]#curl -IkL http://172.25.254.100
HTTP/1.1 302 Found
content-length: 0
location: https://www.timinglee.org/
cache-control: no-cache
HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:31 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:13 GMT
etag: "a-5a244f01f8adc"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8
[root@centos6 ~]#curl -Ik https://www.timinglee.org
HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:50 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:28 GMT
etag: "a-5a244f0fd5175"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值