一篇文章教会你如何使用Haproxy,内含大量实战案例

1. Haproxy 介绍

HAProxy是法国开发者 威利塔罗(Willy Tarreau) 使用C语言编写的自由及开放源代码软件,是一款具备高并发(万级以上)、高性能的TCP和HTTP应用程序代理.

HAProxy运行在当前的硬件上,可以支持数以万计的并发连接,并且它的运行模式使得它可以很简单安全地整合进用户当前的架构中,同时可以保护用户的web服务器不被暴露到网络上.

截止目前GitHub、Bitbucket、Reddit、Twitter等在内的知名网站,都使用了HAProxy.

2. Haproxy 配置

2.1 技术术语

名称说明
慢启动刚启动的服务器,不会被分配到所有的服务请求,而是先分配一部分,服务器状态良好后,再分配一部分,直到逼近服务器可承受范围内极限

2.2 基本配置

文章末尾的 Haproxy实战 基于此配置环境

2.2.1 Haproxy
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.100/24,172.25.254.2
method=manual

nmcli connection reload
nmcli connection up eth0

dnf install haproxy-2.4.22-3.el9_3.x86_64 -y
vim /etc/haproxy/haproxy.cfg
# 前后端分开配置
 67 frontend Webcluster					
 68     bind *:80			
 69     mode http
 70     use_backend Webculuster-host
 71 
 72 backend Webculuster-host
 73     balance roundrobin
 74     server Web1 172.25.254.10:80
 75     server Web2 172.25.254.20:80
# 同时配置前后端 两种方法 二选一即可
listen Webcluster
    bind *:80
    mode http
    balance roundrobin
    server Web1 172.25.254.10:80
    server Web2 172.25.254.20:80
    
systemctl restart haproxy.service
Server1
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.10/24,172.25.254.2
method=manual

nmcli connection reload
nmcli connection up eth0

dnf install nginx -y
echo Web-Server - 172.25.254.10 > /usr/share/nginx/html/index.html
systemctl enable --now nginx.service
2.2.2 Server2
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.20/24,172.25.254.2
method=manual

nmcli connection reload
nmcli connection up eth0

dnf install nginx -y
echo Web-Server - 172.25.254.20 > /usr/share/nginx/html/index.html
systemctl enable --now nginx.service
2.2.3 测试(Windows终端)
# 正常访问
curl 172.25.254.100
Web-Server - 172.25.254.10
curl 172.25.254.100
Web-Server - 172.25.254.20
curl 172.25.254.100
Web-Server - 172.25.254.10
curl 172.25.254.100
Web-Server - 172.25.254.20
# 自动后端检测
[root@Server2 ~]# systemctl stop nginx.service
curl 172.25.254.100
Web-Server - 172.25.254.10
curl 172.25.254.100
Web-Server - 172.25.254.10
curl 172.25.254.100
Web-Server - 172.25.254.10
# 故障或下线服务器 将不再被分配客户端请求

2.3 配置文件

/etc/haproxy/haproxy.cfg 配置文件路径

由两大部分共同构成,分别为

  • global:全局配置段

    • 进程及安全配置相关参数
    • 性能调整相关参数
    • Debug参数
  • proxies:代理配置段

    • defaults:为frontend, backend,listen提供默认配置
    • frontend:前端,相当于nginx中的server {}
    • backend:后端,相当于nginx中的upstream {}
    • listen:同时配置前后端,配置简单,推荐使用
2.3.1 global配置
参数说明
chroot锁定运行目录
deamon以守护进程运行
user, group, uid, gid运行haproxy的用户身份
stats socket套接字文件
nbproc N开启的haproxy worker 进程数,默认进程数是一个
nbthread 1 (和nbproc 互斥)指定每个haproxy进程开启的线程数,默认为每个进程一个 线程
cpu-map 1 0绑定haproxy worker 进程至指定CPU,将第1个work进程绑定至0号CPU
cpu-map 2 1绑定haproxy worker 进程至指定CPU,将第2个work进程绑定至1号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.3.2 proxies 配置
参数说明
defaults默认配置项,针对以下的frontend、backend和listen生效
frontend前端ServerName,类似于LVS服务集群
backend后端服务器组,类似于LVS中的RS服务器
listen将frontend和backend合并在一起配置
  • name字段只能使用大小写字母,数字,短杠 - ,下划线 _ ,点 . 和冒号 : ,并且严格区分大小写
defaults 配置分析
行数(46 defaults)参数说明
47mode httpHAProxy实例使用的连接协议
48log global指定日志地址和记录日志条目的
global表示使用 global 配置段中设定的log值
49option httplog日志记录选项,httplog表示记录与 HTTP 会话相关的各种属性值
包括 HTTP请求、会话状态、连接数、源地址以及连接时间等
50option dontlognulldontlognull表示不记录空会话连接日志
51option http-server-close等待客户端完整HTTP请求的时间
52option forwardfor except 127.0.0.0/8透传客户端真实IP至后端web服务器**(IP透传)**
在Apache配置文件中加入:<br>%{X-Forwarded-For}i 后在Webserver中看日志即可看到地址透传信息
53option redispatch当server id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
54retries 3连接后端服务器失败次数
55timeout http-request 10s等待客户端请求完全被接收和处理的最长时间
56timeout queue 1m设置删除连接和客户端收到503或服务不可用等提示信息前的等待时间
57timeout connect 10s设置等待服务器连接成功的时间
58timeout client 1m设置允许客户端处于非活动状态,即客户端既不发送数据也不接收数据的时间
59timeout server 1m设置服务器超时时间,即服务器处于既不接收也不发送数据的非活动时间
60timeout http-keep-alive 10ssession 会话保持超时时间,此时间段内会转发到相同的后端服务器
61timeout check 10s指定后端服务器健康检查的超时时间
62maxconn 3000最大并发连接数
option http-keep-alive开启与客户端的会话保持
frontend 配置分析
 67 # frontend Webcluster
 68 #    bind *:80
 69 #    mode http
 70 #    use_backend Webculuster-host 调用backend的名称
 
# bind:指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中
# 格式:bind <address>:<port_range> , ...<address>:<port_range>, ...
# 如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1
# backlog <backlog> #针对所有server配置,当前端服务器的连接数达到上限后的后援队列长度,注意:不支持backend

backend 配置分析
  • 定义一组后端服务器
  • backend 的名称必须唯一,并且必须在listen或frontend中事先定义才可以使用,否则服务无法启动
# frontend Your-Name
# bind 172.25.254.100:80
# mode http
# use_backend backend-name #调用backend的名称
 
mode http|tcp	# 指定负载协议类型,必须和对应的frontend保持一致
option	# 配置选项
server	# 定义后端real server,必须指定IP和端口
Server 配置
# server web1 192.168.0.101:80 check inter 3s fall 3 rise 5
# server web2 192.168.0.102:80 check inter 3s fall 3 rise 5
参数说明
check对指定RS进行健康状态检查,如果不加此参数,默认不开启检查
默认对相应的 RS 的IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定端口才能实现健康性检查
addr <IP>可指定的健康状态监测IP,可以是专门的数据网段
port <num>指定的健康状态监测端口
inter <num>健康状态检查间隔时间,默认2000 ms
fall <num>后端服务器从线上转为线下的检查的连续失效次数,默认为3
rise <num>后端服务器从下线恢复上线的检查的连续有效次数,默认为2
weight <weight>权重值默认为1,最大值为256,0 表示不参与负载均衡,但仍接受持久连接
backup将后端服务器标记为备份状态,只在所有非备份主机Down机时提供服务
disabled将后端服务器标记为不可用状态,即维护状态,除了持久模式
将不再接受连接,状态为深黄色,不再接受新用户的请求
redirect prefix将请求临时重定向至其它URL,只适用于http模式
maxconn当前 RS 的最大并发连接数
listen 配置分析

替代 frontend 和 backend 从而简化设置,通常只用于TCP协议的应用

# 	listen webserver_80
# 		bind 172.25.254.100:80
# 		mode http
# 		option forwardfor
# 		server webserver1 192.168.0.101:80 check inter 3s fall 3 rise 5
# 		server webserver2 192.168.0.102:80 check inter 3s fall 3 rise 5

2.4 Socat 工具

2.4.1 Socat 介绍

对 服务器权重 或 其它状态 进行动态调整 可以利用 socat 工具进行调整

Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于NetCAT的增强版

Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式

2.4.2 Socat 使用
# 首先修改 Haproxy 的配置文件,才能正常使用
vim /etc/haproxy/haproxy.cfg
 35     # turn on stats unix socket
 36     stats socket /var/lib/haproxy/stats # 默认情况下只能进行查看,不能进行更改
	--> stats socket /var/lib/haproxy/stats mode 600 level admin

# 安装Socat
dnf install socat -y

# 查看帮助
echo "help" | socat stdio /var/lib/haproxy/stats
......
enable server : enable a disabled server (use 'set server' instead)	# 启用服务器
set maxconn server : change a server's maxconn setting
set server : change a server's state, weight or address # 设置服务器
get weight : report a server's current weight	# 查看权重
set weight : change a server's weight (deprecated)	# 设置权重
......

# 查看haproxy 状态
echo "show info" | socat stdio /var/lib/haproxy/stats
# 查看集群状态
echo "show servers state" | socat stdio /var/lib/haproxy/stats
# 查看集群权重
echo get weight webcluster/web1 | socat stdio
echo get weight webcluster/web2 | socat stdio
# 设置权重
echo "set weight webcluster/web1" | socat stdio
# 下线后端服务器
echo "disable server webcluster/web1" | socat stdio
# 上线后端服务器
echo "enable server webcluster/web1" | socat stdio
2.4.3 Socat的多线程管理

如果Haproxy 开启多进程,那么对进程的 Sock 文件进行操作时,会导致操作是随机,不够准确

指定操作进程,需要用多 Sock 文件方式解决

 35     # turn on stats unix socket
 36     stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1
 37		stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2
 38     nbproc 2
 39     cpu-map 1 0
 40     cpu-map 2 1

则每个进程都有对应的 Sock 文件进行操作

[root@Haproxy ~]# ll /var/lib/haproxy/
srw------- 1 root root 0 811 22:43 stats
srw------- 1 root root 0 811 22:46 stats1
srw------- 1 root root 0 811 22:46 stats2

3. Haproxy 算法

  • HAProxy 通过固定参数 balance 指明对后端服务器的调度算法
  • 固定参数 balance 可以配置在 listen 或 backend 选项中

3.1 静态算法

静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能设置成 0 或 1)只能靠重启HAProxy生效

3.1.1 Rr:基于权重的轮询调度
  • 不支持权重动态调整
  • 不支持服务器慢启动
  • 后端服务器没有数量限制,相当于LVS中的Wrr算法
3.1.2 First
  • 不支持权重动态调整

  • 根据后端服务器在列表中的位置,自上而下进行调度

  • 当前面的服务器的连接数达到上限时,才会把新的请求分配给下一个服务器

  • 忽略服务器权重

3.2 动态算法

  • 基于后端服务器状态可以进行适当调整
  • 最新请求将优先分配给当前负载较低的服务器
  • 权重可以在Haproxy运行时,进行动态调整,无需重启
3.2.1 Roundrobin
  • 基于权重的轮询动态调度算法
  • 支持权重动态调整
  • 支持服务器慢启动
  • 每个后端 Backend 存在上限,最多支持 4095 个 RS
  • Haproxy的默认调度算法
3.2.2 Leastconn
  • 根据当前连接数最少的后端服务器分配请求,而不是权重

  • 当服务器连接数相同,以权重为主

  • 支持权重动态调整

  • 支持服务器慢启动

  • 适合长连接的场景(MySQL等)

3.3 其他算法

此类算法可以根据参数在静态或动态算法中进行转换

3.3.1 Source

基于用户源地址Hash将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端服务器,但当后端服务器数量发生变化时,会导致很多用户的请求转发至新的后端服务器。

默认是静态算法,可以通过Hash-Type选项更改运行模式

Source对后端服务器的选择有两种方法

  • 取模法(Map-Base)
  • 一致性Hash
3.3.2 Map-Base : 取模法

先对Source地址进行Hash计算,再基于服务器总权重的取模(取相除后的余数),最终结果会决定客户端请求被分配到哪个后端服务器上

  • 静态方法,不支持动态调整权重,不支持慢启动
  • 可以实现后端服务器均衡调度
  • 是Source Hash-Type选项 默认使用的算法

缺点:当服务器总权重发生变化时,导致调度结果整体变化

3.3.3 一致性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经过Hash运算后,彼此的值相差不大,在环上呈现紧靠的现象

此时最小Hash值对应的服务器需要处理大部分的服务请求,这种现象称为 一致性Hash环倾斜

解决方案

增加虚拟服务器IP数量

比如:一个后端服务器根据权重为1,则生成1000个虚拟IP,再Hash

另一个后端服务器权重为2,则生成2000的虚拟IP,再Hash

最终在Hash环上生成3000个节点,从而解决Hash环偏斜问题

3.3.4 URL

基于对用户请求的URI的左半部分或整个URL做Hash,再将Hash结果对总权重进行取模后,根据结果将请求转发到后端指定服务器上

  • 适用于后端是缓存服务器场景
  • 静态算法
  • 也可以通过Hash-Type指定Map-Based和一致性Hash

URL算法基于应用层,因此只支持 mode HTTP , 不支持 mode TCP

3.3.5 URL_Param

对用户请求的 URL 中的 Params 部分中的一个参数 Key 对应的 Value 值作 Hash 计算,并由 服务器总权重 相除,根据结果将客户端请求转发到后端指定服务器上

  • 适用于电商网络

用于追踪用户,以确保来自同一个用户的请求始终发往同一个后端服务器

如果没有key,则会使用默认轮询调度算法(Roundrobin)

3.3.6 HDR

针对用户每个HTTP头部(Header)请求中的指定信息做Hash

由 Name 指定的HTTP首部将会被取出并做Hash计算,然后由服务器总权重取模后,根据结果将客户端请求转发到后端指定服务器上

如果没有有效值,则会使用默认轮询调度算法(Roundrobin)

4. Haproxy 实战

4.1 Haproxy 基于Cookie的会话保持

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 67 listen Webcluster
 68     bind *:80
 69     mode http
 70     balance roundrobin
 71     cookie WEBCOOKIE insert nocache indirect
 72     server Web1 172.25.254.10:80 cookie est1 check inter 2 fall 3 rise 5 weight 1
 73     server Web2 172.25.254.20:80 cookie est2 check inter 2 fall 3 rise 5 weight 1
systemctl restart haproxy.service
测试

在这里插入图片描述

[C:\~]$ curl -b WEBCOOKIE=est1 172.25.254.100
Web-Server - 172.25.254.10

[C:\~]$ curl -b WEBCOOKIE=est2 172.25.254.100
Web-Server - 172.25.254.20

4.2 Haproxy 状态页

Haproxy 自带一个状态,方便我们观察服务器的健康状态

4.2.1 状态页配置
参数名称
stats enable基于默认的参数启用stats page
stats hide-version将状态页中haproxy版本隐藏
stats refresh <delay>设定自动刷新时间间隔,默认不自动刷新,过快耗费性能
stats uri <prefix>自定义stats page uri,默认值:/haproxy/status
stats auth : <user>:<passwd>认证时的账号和密码,可定义多个用户,每行指定一个用户
默认:no authentication
stats admin { if | unless } <cond>启用stats page中的管理功能
4.2.2 启用状态页
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 75 listen status
 76     mode http
 77     bind *:1314
 78     stats enable
 79     stats uri /status
 80     stats auth haproxy:1314
[root@Haproxy ~]# systemctl restart haproxy.service

在这里插入图片描述
在这里插入图片描述

可以根据需求将不需要的信息过滤掉

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 82 #frontend main
	......
	......
105 #    server  app4 127.0.0.1:5004 check
# 将 82-105 行注释掉
[root@Haproxy ~]# systemctl restart haproxy.service 

在这里插入图片描述

4.2.3 Haproxy 状态页信息
参数(左上角)说明
pid = 1200 (process #1, nbproc = 1, nbthread = 4)当前PID号;当前进程号;一共多少进程和每个进程多少个线程
uptime = 0d 0h00m09s启动了多长时间
system limits: memmax = unlimited; ulimit-n = 8038系统资源限制:内存;最大打开文件数
maxsock = 8038; maxconn = 4000; maxpipes = 0最大socket=连接数;单进程最大连接数;最大管道数
current conns = 1; current pipes = 0/0; conn rate = 1/sec; bit rate = 0.000 kbps当前连接数;当前管道数;当前连接速率
Running tasks: 0/18; idle = 94 %运行的任务/当前空闲率
参数(正上方)
active UP在线服务器backup UP标记为backup的服务器
active UP, going down监测未通过正在进入down过程backup UP, going down备份服务器正在进入down过程
active DOWN, going updown的服务器正在进入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 maintenanceactive或者backup被人为软下线(人为将weight改成0)
Server 参数
Session rate(每秒的连接会话信息)Cur每秒的当前会话数量
Max每秒新的最大会话数量
Limit每秒新的会话限制量
Sessions(会话信息)Cur当前会话量
Max最大会话量
Limit限制会话量
Total总共会话量
LbTot选中一台服务器所用的总时间
Last和服务器的持续连接时间
BytesIn网络的字节输入总量
Out网络的字节输出总量
Denied(拒绝统计信息)Req拒绝请求量
Resp拒绝回复量
Errors(错误统计信息)Req错误请求量
Conn错误链接量
Resp错误响应量
Warnings(警告统计信息)Retr重新尝试次数
Redis再次发送次数
Server(RS 信息)Status后端机的状态,包括UP和DOWN
LastChk持续检查后端服务器的时间
Wght权重
Act活动链接数量
Bck备份的服务器数量
Chk心跳检测时间
Dwn后端服务器连接后都是DOWN的数量
Dwntme总的downtime时间
ThrtleServer 状态

4.3 Haproxy IP透传

Web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景

4.3.1 七层透传
不做透传
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
46 defaults
......
52     #option forwardfor       except 127.0.0.0/8
[root@Haproxy ~]# systemctl restart haproxy.service

[C:\~]$ curl 172.25.254.100
Web-Server - 172.25.254.20

# 不能显示客户端的IP
[root@Server2 ~]# cat /var/log/nginx/access.log 
172.25.254.100 - - [12/Aug/2024:02:12:08 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.0.1" "-"
做透传
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
46 defaults
......
52     option forwardfor       except 127.0.0.0/8 # 当客户端IP为回环时,不做透传
[root@Haproxy ~]# systemctl restart haproxy.service

[C:\~]$ curl 172.25.254.100
Web-Server - 172.25.254.20

# 显示客户端的IP
[root@Server2 ~]# cat /var/log/nginx/access.log
172.25.254.100 - - [12/Aug/2024:14:13:24 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.0.1" "172.25.254.1"
  • Nginx 默认配置好透传,而Apache则没有
HTTP七层透传
[root@Server1 ~]# yum install httpd -y
[root@Server1 ~]# systemctl disable nginx.service
[root@Server1 ~]# systemctl start httpd

[C:\~]$ curl 172.25.254.100
Web-Server - 172.25.254.10

# 不显示客户端的IP
[root@Server1 ~]# cat /etc/httpd/logs/access_log 
172.25.254.100 - - [12/Aug/2024:14:18:30 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/8.0.1"

[root@Server1 ~]# vim /etc/httpd/conf/httpd.conf
201     LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[root@Server1 ~]# systemctl restart httpd

[C:\~]$ curl 172.25.254.100
Web-Server - 172.25.254.10

[root@Server1 ~]# cat /etc/httpd/logs/access_log
172.25.254.1 172.25.254.100 - - [12/Aug/2024:14:34:31 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/8.0.1"
4.3.2 四层透传
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 66 listen web-server
 67     bind *:80
 68     mode tcp	# TCP 四层透传
 69     balance roundrobin
 70     server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
 71     server web2 172.25.254.20:80 check inter 2 fall 2 rise 5

# 两个服务均不能显示客户端IP
[root@Server1 ~]# cat /etc/httpd/logs/access_log
- 172.25.254.100 - - [12/Aug/2024:02:37:17 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/8.0.1"
[root@Server2 ~]# cat /var/log/nginx/access.log
172.25.254.100 - - [12/Aug/2024:02:37:18 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.0.1" "-"

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 66 listen web-server
 67     bind *:80
 68     mode tcp
 69     balance roundrobin
 70     server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
 71     server web2 172.25.254.20:80 send-proxy check inter 2 fall 2 rise 5
[root@Haproxy ~]# systemctl restart haproxy.service

[root@Server2 ~]# vim /etc/nginx/nginx.conf
 18     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 19                       '$status $body_bytes_sent "$http_referer" '
 20                       '"$proxy_protocol_addr"'	# 新增行
 21                       '"$http_user_agent" "$http_x_forwarded_for"';
 39         listen       80 proxy_protocol;	# 启用此项,将无法直接访问网站,只能通过四层代理访问,如果做七层透传 proxy_protocol 不能有!!!
[root@Server2 ~]# systemctl restart nginx.service
 
# Nginx,而Apache已不支持四层透传
[root@Server2 ~]# cat /var/log/nginx/access.log 
172.25.254.100 - - [12/Aug/2024:02:48:43 +0800] "GET / HTTP/1.1" 200 27 "-" "172.25.254.1""curl/8.0.1" "-"

4.4 Haproxy ACL

4.4.1 ACL 介绍

访问控制列表ACL(Access Control Lists)

  • 一种基于包过滤的访问控制技术
    • 根据设定的条件对经过服务器传输的数据包进行过滤
    • 基于请求报文头部中的源目地址、源目端口、请求方法、文件后缀等信息内容进行匹配并执行进一步操作
4.4.2 ACL 参数
  • 定义ACL
ACLaclnamecriterionflagsoperatorvalue
ACL名称匹配规范匹配模式具体操作符操作对象类型

名称可以使用大小写字母、数字、冒号,点 . 、中横线 - 、下划线 _ ,并且区分大小写

ACL-criterion 匹配规范

即ACL的判断条件

格式模式说明
hdr string提取一个HTTP请求报文的首部
hdr([<name> [,<occc>]])完全匹配字符串header的指定信息, 表示在多值中使用的值的出 现次数
hdr_beg([<name> [,<occc>]])前缀匹配header中指定匹配内容的begin
hdr_end([<name> [,<occc>]])后缀匹配header中指定匹配内容end
hdr_dom([<name> [,<occc>]])域匹配header中的dom(host)
hdr_dir([<name> [,<occc>]])路径匹配header的uri路径
hdr_len([<name> [,<occc>]])长度匹配header的长度匹配
hdr_reg([<name> [,<occc>]])正则表达式匹配自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occc>]])子串匹配header中的uri模糊匹配 模糊匹配c 报文中a/b/c也会匹 配
ACL-flags 匹配模式
参数说明
-i不区分大小写
-m使用指定的正则表达式匹配方法
-n不做DNS解析
-u禁止ACL重名
ACL-operator 具体操作符
  • 整数比较
    • 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进行匹配
ACL-value 操作对象
参数说明
Boolean布尔值
integer or integer range整数或整数范围,比如用于匹配端口范围
IP address / networkIP地址或IP范围
string
exact精确比较
substring子串
suffix后缀比较
prefix前缀比较
subdir路径
domain域名
regular expression正则表达式
hex block16进制
多个ACL的组合调用方式
  • 多个ACL的逻辑处理

    • 与:默认使用
    • 或:使用 or 或 || 表示
    • 否定:使用 ! 表示
  • 多个ACL调用方式

if A B 		# 与关系,ACL中A和B都要满足为true,默认为与
if A || B 	# 或,ACL中A或者B满足一个为true
if ! A 				# 非,取反,不满足ACL才为true
4.4.3 基于 ACL 匹配 访问路径 实现动静分离
Haproxy
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 66 frontend webcluster
 67     bind *:80
 68     mode http
 69     acl static  path_sub    -m  sub static
 70     acl php     path_sub    -m  sub php
 71     ##################################
 72     use_backend webcluster-host if php
 73     default_backend default-host
 74 
 75 backend webcluster-host
 76     mode http
 77     server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
 78 
 79 backend default-host
 80     mode http
 81     server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@Haproxy ~]# systemctl restart haproxy.service
Server-HTTP
yum install php -y

mkdir -p /var/www/html/php
vim /var/www/html/php/index.html
<?php
        phpinfo();
?>

systemctl restart httpd
Server-Nginx
mkdir /usr/share/nginx/html/static -p
echo static - 172.25.254.20 Nginx > /usr/share/nginx/html/static/index.html

# 如果没有做四层透传,则忽略此步骤
[root@Server2 ~]# vim /etc/nginx/nginx.conf
 18     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 19                       '$status $body_bytes_sent "$http_referer" '
 20                       '"$proxy_protocol_addr"'	# 将此行删去
 21                       '"$http_user_agent" "$http_x_forwarded_for"';
 39         listen       80;	# 将四层透传参数 proxy_protocol 去掉
systemctl restart nginx.service
测试

在这里插入图片描述
在这里插入图片描述

4.5 Haproxy 错误页面

对指定的页面错误代码进行重定向,优雅地显示错误页面

使用 errorfile 指令,可以自定义错误页面

4.5.1 自定义错误页面
# Haproxy 默认使用的错误错误页面
[root@Haproxy ~]# rpm -ql haproxy | 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
格式
errorfile <code> <file>
# code:支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504
# file:包含完整HTTP响应头的错误页文件的绝对路径.建议后缀 .http 方便与一般的HTML文件相区分
配置
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 63     errorfile 503 /haproxy/errorpages/code-503.http
 
[root@Haproxy ~]# mkdir /haproxy/errorpages/ -p
[root@Haproxy ~]# cp /usr/share/haproxy/503.http /haproxy/errorpages/code-503.http
[root@Haproxy ~]# vim /haproxy/errorpages/code-503.http
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8

<html><body><h1>!!! 503 !!!</h1>
</body></html>

[root@Haproxy ~]# systemctl restart haproxy.service
Server
systemctl stop nginx.service
测试

在这里插入图片描述

4.5.2 重定向错误页面

使用 errorloc 指令,遇到错误代码时,重定向错误页面

配置
[root@Haproxy ~]#  vim /etc/haproxy/haproxy.cfg
 63     errorloc 503 https://www.baidu.com
测试

在这里插入图片描述

4.6 Haproxy 四层负载

主要应用于HTTP以外的TCP协议应用服务访问的场景

  • MySQL、Redis
  • Memcache、RabbitMQ

注意:如果使用frontend和backend,一定在 frontend 和 backend 段中都指定mode tcp

4.6.1 Haproxy
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
 82 listen mysql
 83     bind *:3306
 84     mode tcp
 85     balance static-rr
 86     server mysql1 172.25.254.10:3306 check inter 2 fall 2 rise 5
 87     server mysql2 172.25.254.20:3306 check inter 2 fall 2 rise 5

[root@Haproxy ~]# systemctl restart haproxy.service
[root@Haproxy ~]# yum install mariadb -y
4.6.2 Server1
[root@Server1 ~]# yum install mariadb-server -y

[root@Server1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
 16 [mysqld]
 17 server-id=1
 
[root@Server1 ~]# mysql
MariaDB [(none)]> CREATE USER est@'%' identified by 'est';
MariaDB [(none)]> GRANT ALL ON *.* TO est@'%';
[root@Server1 ~]# systemctl start mariadb
4.6.2 Server2
[root@Server2 ~]# yum install mariadb-server -y

[root@Server2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
 16 [mysqld]
 17 server-id=2
 
[root@Server2 ~]# mysql
MariaDB [(none)]> CREATE USER est@'%' identified by 'est';
MariaDB [(none)]> GRANT ALL ON *.* TO est@'%';
[root@Server1 ~]# systemctl start mariadb
4.6.3 测试
[root@Haproxy ~]# mysql -uest -pest -h 172.25.254.100
MariaDB [(none)]> SELECT @@server_id;
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+
MariaDB [(none)]> show variables like 'hostname';
+---------------+-------------+
| Variable_name | Value       |
+---------------+-------------+
| hostname      | Server2.org |
+---------------+-------------+

MariaDB [(none)]> SELECT @@server_id;
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+
MariaDB [(none)]> show variables like 'hostname';
+---------------+-------------+
| Variable_name | Value       |
+---------------+-------------+
| hostname      | Server1.org |
+---------------+-------------+

4.7 Haproxy https实现

4.7.1 Haproxy
mkdir /etc/haproxy/certs/

openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/haproxy.org.key -x509 -days 365 -out /etc/haproxy/certs/haproxy.org.crt
# Country Name (2 letter code) [XX]:CN
# State or Province Name (full name) []:Shanghai
# Locality Name (eg, city) [Default City]:SHANGHAI
# Organization Name (eg, company) [Default Company Ltd]:Haproxy
# Organizational Unit Name (eg, section) []:Webserver
# Common Name (eg, your name or your server's hostname) []:www.est.org
# Email Address []:admin@est.org

[root@Haproxy ~]# cat /etc/haproxy/certs/haproxy.org.key /etc/haproxy/certs/haproxy.org.crt > /etc/haproxy/certs/haproxy.pem

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen web-https
    bind *:443 ssl crt /etc/haproxy/certs/haproxy.pem
    mode http
    balance roundrobin
    server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
    server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
 
 [root@Haproxy ~]# systemctl restart haproxy.service
4.7.2 Server1
systemctl restart nginx.service
4.7.2 Server2
systemctl restart nginx.service
4.7.3 测试

在这里插入图片描述

在这里插入图片描述

4.7.4 全站加密
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend Webcluster
    bind *:80
    mode http
    redirect scheme https if !{ ssl_fc }

listen web-https
    bind *:443 ssl crt /etc/haproxy/certs/haproxy.pem
    mode http
    balance roundrobin
    server web1 172.25.254.10:80 check inter 2 fall 2 rise 5
    server web2 172.25.254.20:80 check inter 2 fall 2 rise 5
[root@Haproxy ~]# systemctl restart haproxy.service
测试

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值