> 技术文档 > 负载均衡Haproxy

负载均衡Haproxy


简介

HAProxy是一款高性能、开源的负载均衡器反向代理服务器,主要用于 HTTPTCP等协议的流量分发,广泛应用于高并发高可用的网络架构中

HAProxy是法国威利塔罗(Willy Tarreau)使用C语言开发的一个开源软件

企业版:https://www.haproxy.com/

社区版:https://www.haproxy.org/

GitHub:https://github.com/haprox

配置

官方文档:https://docs.haproxy.org/

配置文件:/etc/haproxy/haproxy.cfg

Haproxy配置由两大部分组成,分别是

全局配置段:global 代理配置段:proxies 进程及安全配置相关参数 defaults段:为frontend、backend、listen提供默认配置 性能调整相关参数 frontend段:前端配置 Debug参数 backend段:后端配置 listen:前端 + 后端配置,生成推荐使用

global部分

配置名 数值 功能 log 127.0.0.1 local2 全局的syslog服务器,最多定义两个,需要开启UDP协议 chroot /var/lib/haproxy 指定运行目录 pidfile /var/run/haproxy.pid 指定pid文件路径 maxconn 4000 每个Haproxy进程的最大并发连接数 maxsslconn n 每个Haproxy进程ssl最大连接数,适用于haproxy配置证书的情况下 maxconnrate n 每个进程每秒创建的最大连接数量 nbproc n 开启Haproxy worker进程数,默认一个 cpu-map 1 0 绑定Haproxy worker进程到指定CPU cpu-map 2 1 将2个work进程绑定到1号CPU上 nbthread(与nbproc互斥) n 每个Haproxy进程的线程数,默认1进程1线程 user,group,uid,gid haproxy,haproxy,xxx,xxx 运行Haproxy的用户身份 spread-checks n 后端Server状态check随机提前或延迟百分比时间,建议20%-50%之间,默认值0 daemon 以守护进程运行 stats socket /var/lib/haproxy/stats /var/lib/haproxy/stats 套接字文件 ssl-default-bind-ciphers PROFILE=SYSTEM PROFILE=SYSTEM HAProxy作为服务器使用的加密套件 ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM PROFILE=SYSTEM HAProxy作为客户端使用的加密套件
多进程
[root@Haproxy ~]# yum install haproxy -y[root@Haproxy ~]# systemctl enable --now haproxy[root@Haproxy ~]# pstree -p | grep haproxy

在这里插入图片描述

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfgstats socket /var/lib/haproxy/statsnbproc 2cpu-map 1 0cpu-map 2 1[root@Haproxy ~]# systemctl restart haproxy.servic[root@Haproxy ~]# pstree -p | grep haproxy

在这里插入图片描述

在这里插入图片描述

多进程和多线程互斥,两个不能同时配置

多线程
# 未开启多线程时[root@Haproxy ~]# pstree -p | grep haproxy[root@Haproxy ~]# cat /proc/31104/status | grep Threads

在这里插入图片描述

# 开启多线程时[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfgstats socket /var/lib/haproxy/statsnbthread 3[root@Haproxy ~]# systemctl restart haproxy.service

在这里插入图片描述

[root@Haproxy ~]# pstree -p | grep haproxy  |-haproxy(31186)---haproxy(31188)-+-{haproxy}(31189)  |  `-{haproxy}(31190)[root@Haproxy ~]# cat /proc/31188/status | grep ThreadsThreads: 3[root@Haproxy ~]# cat /proc/31189/status | grep ThreadsThreads: 3

在这里插入图片描述

proxies部分

又细分为三小段;listen段将fronted和backend合并

配置段 功能 defaults 默认配置项;针对frontend、backend、listen生效 frontend 前端Servername,类似LVS的服务集群 backup 后端RealServer,类似LVS的RS服务器 listen 将frontend和backup合并配置
defaults段
配置名 数值 功能 defaults name 默认配置项,可以有多个name,也可以没有 mode http 使用的连接协议 log global 指定日志地址和记录日志的设备;
global:使用global段中的log值 option httplog 日志记录选项;
httplog:记录与HTTP相关属性值 option dontlognull 不记录空会话连接日志 option http-server-close 等待客户端完整HTTP请求的时间,此处等待10s option forwardfor except 127.0.0.0/8 透传客户端真实IP到后端Web服务器;except 127.0.0.0/8:排除内网IP option redispatch 当服务器不可用时,将请求重新分发到其他服务器(默认只重试一次) option http-keep-alive 启用HTTP长连接支持,即会话保持 retries 3 连接后端服务器失败时的重试次数 timeout http-request 10s 等待客户端请求完全被接收和处理的最长时间 timeout queue 1m 请求在队列中等待的最长时间 timeout connect 10s 连接后端服务器的超时时间 timeout client 1m 客户端空闲超时时间,即允许客户端处于既不接收也不发送数据的非活动时间 timeout server 1m 服务器空闲超时时间,即允许服务器处于既不接收也不发送数据的非活动时间 timeout http-keep-alive 10s HTTP长连接的空闲超时时间 timeout check 10s 后端服务器健康检查的超时时间 maxconn 3000 每个进程允许的最大并发连接数 default-server inter 1000 weight 3 为所有后端服务器设置默认参数
inter 1000 表示健康检查间隔为 1秒
weight 3 表示默认权重为 3
frontend段
frontend namebind *:80mode httpuse_backend use_name
配置名 数值 功能 frontend xxx 定义frontend的名字 bind IP:Port,… 指定Haproxy监听地址;支持IPV4和IPV6;支持同时监听多个端口
如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1 mode http、tcp、udp… 指定负载协议类型;frontend与调用的backend保持一致 use_backend backend name 将请求转发到backend name后端 backlog 当前端服务器的连接数达到上限时,等待处理的连接请求的后援队列长度
用于高并发场景下缓冲过量的连接请求,避免直接拒绝客户端连接
不支持backend
backend段

backend名称必须唯一,且必须在listen或fronted中事先定义才能使用,否则服务报错

backend namemode httpserver name 192.168.0.87:80 check inter 3s fall 3 rise 5server name 192.168.0.89:80 check inter 3s fall 3 rise 5
option参数 功能 httpchk 通过发送 HTTP 请求并验证响应状态码来检查服务健康 smtpchk 通过 SMTP 协议握手验证邮件服务器可用性 mysql-check 通过 MySQL 协议验证数据库服务可用性 pgsql-check 通过 PostgreSQL 协议验证数据库服务可用性 ssl-hello-chk 验证服务器是否能正常完成 SSL/TLS 握手,用于 HTTPS 服务
Server行
参数 功能 name 本行server的名字 addr 指定server的IP,可以是专门的数据网段 port 指定server的端口 check 对当前server进行健康状态检查,默认不开启检查;
对相应的IP和端口利用TCP连接进行周期性健康险检查
必须指定端口才能实现健康检查 inter 健康状态检查间隔时间,默认2000ms fall 连续健康检查失败 n 次后标记为下线,默认 3 rise 连续健康检查成功 n 次后标记为上线,默认 2 weight 默认为1,最大256;0 表示不参与负载均衡,但能接受持久连接 backup 标记server为备份状态;仅当其他服务器全部宕机时提供服务 disabled 将server标记为不可用状态,即维护状态
保留持久连接,不再接受新请求,状态页显示深黄色 pedirect 将请求临时重定向到其他URL,只适用于HTTP模式 maxconn 单server的最大并发连接数
listen段

通常只用于TCP协议的应用,是前两者的结合配置

listen namebind 192.168.0.87:80mode httpbalance static-rr# 使用的负载均衡算法server mariadb1 192.168.0.87:3306 check inter 3s fall 3 rise 5server mariadb2 192.168.0.89:3306 check inter 3s fall 3 rise 5

socat工具

Socat 是 Linux 下的一个多功能的网络工具

它可以在两个数据流之间建立连接并转发数据,且支持众多协议和链接方式

可以对服务器权重和状态进行动态调整

基本应用

修改配置文件后,才能正常使用,默认情况下只能查看,不能进行修改

当Haproxy使用特定负载算法时,无法动态调整服务器权重

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg# turn on stats unix socketstats socket /var/lib/haproxy/stats mode 600 level admin[root@Haproxy ~]# systemctl restart haproxy.service

在这里插入图片描述

[root@Haproxy ~]# yum install socat -y# 查看帮助[root@Haproxy ~]# echo \"help\" | socat stdio /var/lib/haproxy/statsdisable server: disable a server for maintenance# 下线服务器enable server : enable a disabled server# 上线服务器set server : change a server\'s state, weight or address# 修改状态、权重、IPget weight : report a server\'s current weight# 查看权重set weight : change a server\'s weight (deprecated)# 修改权重......
# 查看Haproxy全局信息(Uptime、Maxsock、CurrConns...)echo \"show info\" | socat stdio /var/lib/haproxy/stats# 查看集群状态echo \"show servers state\" | socat stdio /var/lib/haproxy/stats# 查看集群权重echo \"get weight nginx/static\" | socat stdio /var/lib/haproxy/stats1 (initial 1)# 当前动态权重(配置文件中设置的初始权重)# 设置权重(范围为0 - 256)echo \"set weight nginx/static 3\" | socat stdio /var/lib/haproxy/stats3 (initial 1)# 下线后端服务器echo \"disable server webcluster/web1\" | socat stdio /var/lib/haproxy/stats# 上线后端服务器echo \"enable server webcluster/web1\" | socat stdio /var/lib/haproxy/stats
多进程处理

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

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

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg  # turn on stats unix socket 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# 经过设置后,每个进程都有对应的sock文件提供操作[root@Haproxy ~]# ll /var/lib/haproxy/

在这里插入图片描述

在这里插入图片描述

ACL

格式
acl aclname criterion flags operator value acl 名称 匹配规范 匹配模式 具体操作符 操作对象
匹配规范

hdr string:提取HTTP请求报文的首部

hdr([[,]]) 完全匹配 header的指定信息;occ表示在多值中使用的值出现的次数 hdr_beg 前缀匹配 header中指定匹配内容的begin hdr_end 后缀匹配 header中指定匹配内容的end hdr_dom 域名匹配 header中的dom(host) hdr_dir 路径匹配 header的 uri 路径 hdr_len 长度匹配 header的长度匹配 hdr_reg 正则表达式匹配 自定义表达式模糊匹配 hdr_sub 子串匹配 header中的 uri 模糊匹配

匹配规范还包括(base类、path类、url类)

base string:返回主机头请求的路径部分的连接,请求从主机名开始,并在问号之前结束,对虚拟主机有用

://:@#:/;#?#

path:提取请求的URL路径,此路径从第一个斜杠开始,在问号之前结束(无主机部分)

url:提取请求中的整个URL

匹配模式
-i不区分大小写-m使用指定的正在表达式匹配方法-n不做DNS解析-u禁止ACL重名,否则多个同名ACL匹配或关系
具体操作符
整数比较
eq 等于 ge 大于等于 gt 大于 le 小于等于 lt 小于
字符比较
-m str 提取的字符串必须与模式完全相同 -m sub 提取的字符串中包含指定子串 -m beg 提取的字符串以指定模式开头 -m end 提取的字符串以指定模式结尾 -m dir 路径中的任一目录部分匹配模式(用斜线 / 分隔的字符串) -m dom 域名的任一组成部分匹配模式(用点 . 分隔字符串)
操作对象

对象类型

Boolean 布尔值 Integer/Range 整数或整数范围 IP Address/Network IP 地址 / IP 范围 String 字符串 -m str 精确匹配 -m sub 子串匹配 -m beg 前缀匹配 -m end 后缀匹配 -m dir 路径匹配 -m dom 域名匹配 Regular Expression 正则表达式 Hex Block 十六进制
组合调用方式
多个ACL逻辑处理

与:默认使用

或:or 或 || 表示

否定:! 表示

多个ACL调用方式
if a1 a2 与关系,acl中a和b 都要满足为true,默认调用方式 if a1 || a2
if a1 or a2 或关系,acl中a1或a2满足一个为true if !a1 非,取反,不满足acl才为true

算法

HAProxy通过固定参数 balance 指明对后端服务器的调度算法

balance 参数可以配置在listen或backend选项中

HAProxy的调度算法分为静态和动态调度算法,有些算法可以根据参数在静态和动态算法中相互转换

静态算法

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

static-rr

基于权重的轮询调度,权重只能在配置文件中静态设置

  • 不支持权重动态调整
  • 不支持服务器慢启动
  • 后端服务器没有数量限制

慢启动:服务器刚刚启动时,先给一部分访问,承受住后,再逐渐增加

cat /etc/haproxy/haproxy.cfglisten nginx bind 172.25.254.100:80 mode http balance static-rr server rs1 192.168.0.87:80 weight 1 check inter 3s fall 3 rise 5 server rs2 192.168.0.89:80 weight 1 check inter 3s fall 3 rise 5for i in {1..10}; do curl 172.25.254.100; done
first

根据服务器在列表中的位置,自上而下进行调度,当第一台服务器的连接数达到上限,新请求才会分配给下一台服务

  • 忽略服务器权重
  • 不支持权重动态调整
vim /etc/haproxy/haproxy.cfglisten WebCluster bind 172.25.254.87:80 mode http balance first server RS1 172.25.254.88:80 weight 1 maxconn 1 check inter 3s fall 3 rise 5 server RS2 172.25.254.99:80 weight 3 check inter 3s fall 3 rise 5# 一个终端一直访问 while true; do curl 172.25.254.87; done# 另一个终端也一样 while true; do curl 172.25.254.87; done 可以观察到有访问到 172.25.254.99......Web-Server - 172.25.254.88Web-Server - 172.25.254.99Web-Server - 172.25.254.88......

动态算法

  • 基于后端服务器状态进行调度适当调整

  • 新请求将优先调度至当前负载较低的服务器

  • 权重可以在haproxy运行时动态调整无需重启

roundrobin

基于权重的轮询动态调度算法

  • 支持权重动态调整,不同于LVS中的 rr 轮询模式

  • 支持慢启动(新加的服务器会逐渐增加转发数)

  • 默认调度算法,使用广泛

其每个后端backend中最多支持4095个real server

vim /etc/haproxy/haproxy.cfglisten WebCluster bind 172.25.254.87:80 mode http balance roundrobin server RS1 172.25.254.88:80 weight 1 check inter 3s fall 3 rise 5 server RS2 172.25.254.99:80 weight 2 check inter 3s fall 3 rise 5for i in {1..10}; do curl 172.25.254.87; doneWeb-Server - 172.25.254.99Web-Server - 172.25.254.99Web-Server - 172.25.254.99Web-Server - 172.25.254.88......# 动态调整权重echo \"set weight WebCluster/RS2 1\" | socat stdio /var/lib/haproxy/statsecho get weight WebCluster/RS2 | socat stdio /var/lib/haproxy/stats1 (initial 2)echo get weight WebCluster/RS1 | socat stdio /var/lib/haproxy/stats1 (initial 1)for i in {1..10}; do curl 172.25.254.87; doneWeb-Server - 172.25.254.88Web-Server - 172.25.254.99......
leastconn

加权最少连接

  • 根据当前连接数最少的后端服务器分配请求,而非权重
  • 当服务器连接数相同,以权重为主
  • 支持权重动态调整
  • 支持服务器慢启动
  • 适合长连接的场景

其他算法

其它算法即可作为静态算法,又可以通过选项成为动态算法

source

源地址哈希,默认为静态方式

基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端Web服务器

但当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器

可以通过hash-type支持的选项更改运行模式

两种转发请求到后端服务器的计算方式,分别是取模法一致性hash

当客户端是一个家庭,所有家庭成员的访问流量都会被定向到一台服务器,这是source算法的缺陷

map-base

取模法

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

静态算法:不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度

当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化导致调度结果整体改变(导致已建立的会话内容全部丢失)

一致性hash

一致性哈希

当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动

动态算法,支持使用socat等工具进行在线权重调整,支持慢启动

在这里插入图片描述

逆时针方向,就近原则选取服务器

hash环偏斜问题:

当多个服务器IP经过Hash运算后,彼此的值相差不大,在环上呈现紧靠的现象,此时最小Hash值对应的服务器需要处理大部分的服务请求,这种现象称为一致性Hash环倾斜

解决方案:

增加虚拟服务器IP数量,比如一个后端服务器根据权重为1生成1000个虚拟IP,再hash。而后端服务器权重为2则生成2000的虚拟IP,再bash,最终在hash环上生成3000个节点,从而解决hash环偏斜问题

在这里插入图片描述

uri

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

适用于后端是缓存服务器场景

默认是静态算法,也可以通过hash-type指定map-basedconsistent,决定使用取模法还是一致性hash

此算法基于应用层,所以只支持 mode http ,不支持 mode tcp

url_param

对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器

通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server

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

hdr

针对用户每个http头部(header)请求中的指定信息做hash

由 name 指定的 http首部 将会被取出并做hash计算

然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认轮询调度算法

算法总结

调度算法 适用协议 static-rr tcp/http first tcp/http roundrobin tcp/http leastconn tcp/http source tcp/http Uri http url_param http hdr http

应用

环境

主机版本:Linux-9_4.x86_64

主机名 IP 网卡 Client 172.25.254.88 eth0 Haproxy 172.25.254.100(公网) eth0 192.168.0.100(私网) eth1(仅主机模式) RS1 192.168.0.87 eth0(仅主机模式) RS2 192.168.0.89 eth0(仅主机模式)

安装

软件包:https://github.com/haproxy/wiki/wiki/Packages

[root@Haproxy ~]# yum install haproxy.x86_64 -y &> /dev/null[root@Haproxy ~]# haproxy -v[root@Haproxy ~]# systemctl enable --now haproxy.service

在这里插入图片描述

基本应用

[root@RS1/2 ~]# yum install nginx -y &> /dev/null[root@RS1/2 ~]# echo \"192.168.0.87\" > /usr/share/nginx/html/index.html[root@RS1/2 ~]# systemctl enable --now nginx.service[root@RS1 ~]# curl 192.168.0.89192.168.0.89[root@RS2 ~]# curl 192.168.0.87192.168.0.87

在这里插入图片描述

# 除global和defaults段,其他地方均要注释掉[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg#---------------------------------------------------------------------# main frontend which proxys to the backends#---------------------------------------------------------------------listen nginx bind 172.25.254.100:80 mode http balance static-rr server rs1 192.168.0.87:80 weight 1 check server rs2 192.168.0.89:80 weight 1 check[root@Haproxy ~]# systemctl restart haproxy.service

在这里插入图片描述

[root@Client ~]# for i in {1..10}; do curl 172.25.254.100; done

在这里插入图片描述

高级应用

Haproxy 错误页

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

使用 errorfile 和 errorloc 参数,实现自定义各种错误页面

# Haproxy默认使用的错误页面[root@Haproxy ~]# rpm -ql haproxy | grep -E http$

在这里插入图片描述

自定义错误页面
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg...... maxconn  3000 errorfile 503 /haproxy/errorpages/503page.http#---------------------------------------------------------------------# main frontend which proxys to the backends#---------------------------------------------------------------------[root@Haproxy ~]# mkdir /haproxy/errorpages/ -p[root@Haproxy ~]# cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http[root@Haproxy ~]# cat /haproxy/errorpages/503page.httpHTTP/1.0 503 Service Unavailable^MCache-Control: no-cache^MConnection: close^MContent-Type: text/html;charset=UTF-8^M^M<html><body><h1>什么水果最让人感到有压力?</h1><h1>鸭梨,因为\"压力\"(鸭梨)山大</h1></body></html>[root@Haproxy ~]# systemctl restart haproxy.service[root@RS1/2 ~]# systemctl stop nginx.service

在这里插入图片描述

在这里插入图片描述

通过浏览器访问172.25.254.100

在这里插入图片描述

重定向错误页面

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

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg...... maxconn  3000 errorloc 503 https://www.baidu.com#---------------------------------------------------------------------# main frontend which proxys to the backends#---------------------------------------------------------------------[root@RS1/2 ~]# systemctl stop nginx

在这里插入图片描述

Haproxy HTTPS实现
[root@Haproxy ~]# mkdir /etc/haproxy/certs/[root@Haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/ooovooo.org.key -x509 -days 365 -out /etc/haproxy/certs/ooovooo.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]:QAQ# Organizational Unit Name (eg, section) []:QWQ# Common Name (eg, your name or your server\'s hostname) []:www.ooovooo.org# Email Address []:admin@ovo.org[root@Haproxy ~]# cat /etc/haproxy/certs/ooovooo.org.key /etc/haproxy/certs/ooovooo.org.crt > /etc/haproxy/certs/ooovooo.org.pem[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfglisten nginx bind *:443 ssl crt /etc/haproxy/certs/ooovooo.org.pem mode http balance static-rr server rs1 192.168.0.87:80 weight 1 check server rs2 192.168.0.89:80 weight 1 check [root@Haproxy ~]# systemctl restart haproxy.service [root@RS1/2 ~]# systemctl restart nginx.service

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

全站加密
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend nginx-https bind *:80 mode http redirect scheme https if !{ ssl_fc }listen nginx bind *:443 ssl crt /etc/haproxy/certs/ooovooo.org.pem mode http balance static-rr server rs1 192.168.0.87:80 weight 1 check server rs2 192.168.0.89:80 weight 1 check[root@Haproxy ~]# systemctl restart haproxy.service

在这里插入图片描述

在这里插入图片描述

Haproxy 状态页

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

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

基于Cookie的会话保持
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfglisten nginx bind *:443 ssl crt /etc/haproxy/certs/ooovooo.org.pem mode http balance static-rr cookie QAQ-WebServer insert nocache indirect server rs1 192.168.0.87:80 cookie est1 weight 1 check server rs2 192.168.0.89:80 cookie est2 weight 1 check[root@Haproxy ~]# systemctl restart haproxy.service

在这里插入图片描述

在这里插入图片描述

IP透传

NGinx日志:/var/log/nginx/access.log

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

四层透传

Apache不支持原生四层透传(TCP 转发),可以在四层代理的配合下做到透传

未配置透传
# 将前面的配置删掉,保证环境的干净[root@HAproxy ~]# vim /etc/haproxy/haproxy.cfglisten nginx bind *:80 mode tcp balance roundrobin server rs1 192.168.0.87:80 weight 1 check server rs2 192.168.0.89:80 weight 1 check[root@HAproxy ~]# systemctl restart haproxy.service[root@RS1 ~]# > /var/log/nginx/access.log[root@Client ~]# for i in {1..10}; do curl 172.25.254.100; done# 不记录客户端真实 IP 地址[root@RS1 ~]# cat /var/log/nginx/access.log

在这里插入图片描述

在这里插入图片描述

配置透传
# 仅开启RS2[root@HAproxy ~]# vim /etc/haproxy/haproxy.cfglisten WebServer bind *:80 mode tcp balance roundrobin server rs1 192.168.0.87:80 weight 1 check server rs1 192.168.0.87:80 weight 1 check send-proxy # send-proxy 开启透传[root@HAproxy ~]# systemctl restart haproxy.service[root@Server2 ~]# vim /etc/nginx/nginx.confhttp { log_format main \'$remote_addr - $remote_user [$time_local] \"$request\" \' \'\"$proxy_protocol_addr\"\'# 新增行\'$status $body_bytes_sent \"$http_referer\" \'\'\"$http_user_agent\" \"$http_x_forwarded_for\"\';...... server {# 没有 proxy_protocol 参数无法访问,只能通过四层代理访问;# 并且做七层透传时 proxy_protocol 参数不能有 listen 80 proxy_protocol; listen [::]:80;[root@RS2 ~]# systemctl restart nginx.service[root@RS1/2 ~]# > /var/log/nginx/access.log[root@Client ~]# for i in {1..10}; do curl 172.25.254.100; done# 记录客户端真实 IP 地址[root@RS1/2 ~]# cat /var/log/nginx/access.log

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

七层透传

Nginx七层默认配置好透传,而Apache则没有,需要进行相应配置

[root@HAproxy ~]# vim /etc/haproxy/haproxy.cfglisten WebServer bind *:80 mode http balance roundrobin server rs1 192.168.0.87:80 weight 1 check server rs2 192.168.0.89:80 weight 1 check[root@HAproxy ~]# systemctl restart haproxy.service# 还原配置[root@RS2 ~]# vim /etc/nginx/nginx.confhttp { log_format main \'$remote_addr - $remote_user [$time_local] \"$request\" \'\'$status $body_bytes_sent \"$http_referer\" \'\'\"$http_user_agent\" \"$http_x_forwarded_for\"\';...... server { listen80;[root@RS2 ~]# systemctl restart nginx.service[root@RS1 ~]# > /var/log/nginx/access.log[root@Client ~]# for i in {1..10}; do curl 172.25.254.88; done# Nginx 七层默认开启透传[root@RS1 ~]# cat /var/log/nginx/access.log

在这里插入图片描述

在这里插入图片描述

# 关闭 Nginx 七层透传[root@HAproxy ~]# vim /etc/haproxy/haproxy.cfgdefaults......# 在转发客户端请求时,HAProxy会在HTTP请求头中添加X-Forwarded-For字段,其中包含客户端的真实IP地址# 来自本地回环地址的请求,HAProxy 不会添加 X-Forwarded-For 头# option forwardfor except 127.0.0.0/8[root@HAproxy ~]# systemctl restart haproxy.service[root@RS1 ~]# > /var/log/nginx/access.log[root@Client ~]# for i in {1..10}; do curl 172.25.254.100; done[root@RS1 ~]# cat /var/log/nginx/access.log

在这里插入图片描述

在这里插入图片描述

Apache七层透传
[root@RS1 ~]# systemctl stop nginx.service[root@RS1 ~]# dnf install httpd -y[root@RS1 ~]# systemctl enable --now httpd[root@RS1 ~]# echo 192.168.0.87 > /var/www/html/index.html[root@RS1 ~]# curl 192.168.0.87192.168.0.87[root@RS1 ~]# > /etc/httpd/logs/access_log[root@Client ~]# for i in {1..10}; do curl 172.25.254.100; done# 默认关透传[root@RS1 ~]# cat /etc/httpd/logs/access_log

在这里插入图片描述

# 开透传# /etc/haproxy/haproxy.cfg中需要option forwardfor except 127.0.0.0/8未被注释[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg option forwardfor except 127.0.0.0/8[root@Haproxy ~]# systemctl restart haproxy.service[root@RS1 ~]# vim /etc/httpd/conf/httpd.conf201LogFormat \"%{X-Forwarded-For}i %h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined202 LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common[root@RS1 ~]# systemctl restart httpd[root@RS1 ~]# > /etc/httpd/logs/access_log[root@Client ~]# for i in {1..10}; do curl 172.25.254.100; done[root@RS1 ~]# cat /etc/httpd/logs/access_log

在这里插入图片描述

在这里插入图片描述

ACL-匹配访问路径实现动静分离

注意:四层透传下,无法完成此实验

[root@RS1 ~]# yum remove httpd -y[root@RS1/2 ~]# systemctl enable --now nginx.service[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend nginx bind *:80 mode http acl staticpath_sub-msubstatic acl phppath_sub-m subphp use_backendphp-serverifphp default_backend default-serverbackend php-server mode http server php 192.168.0.87:80 checkbackend default-server mode http server nginx 192.168.0.89:80 check[root@Haproxy ~]# systemctl restart haproxy.service[root@RS1 ~]# yum install php -y[root@RS1 ~]# mkdir /usr/share/nginx/html/php -p[root@RS1 ~]# vim /usr/share/nginx/html/php/index.php<?php phpinfo();?>[root@RS1 ~]# systemctl enable --now php-fpm.service[root@RS2 ~]# mkdir /usr/share/nginx/html/static -p[root@RS2 ~]# echo static - 172.25.254.89 Nginx > /usr/share/nginx/html/static/index.html

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Haproxy 四层负载
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfglisten mysql bind *:3306 mode tcp balance static-rr server rs1 192.168.0.87:3306 check server rs2 192.168.0.89:3306 check[root@Haproxy ~]# systemctl restart haproxy.service

在这里插入图片描述

[root@RS1/2 ~]# yum install mariadb-server -y[root@RS1 ~]# vim /etc/my.cnf!includedir /etc/my.cnf.d[mysqld]server-id=1[root@RS2 ~]# vim /etc/my.cnf!includedir /etc/my.cnf.d[mysqld]server-id=2[root@RS1/2 ~]# systemctl enable --now mariadb[root@RS1/2 ~]# mysql -e \"grant all on *.* to ovo@\'%\' identified by \'aaa\';\"[root@RS1/2 ~]# systemctl restart mariadb.service[root@Client ~]# yum install mariadb -y[root@Client ~]# mysql -uovo -paaa -h 172.25.254.100 -e \'select @@server_id;\'

在这里插入图片描述