一 负载均衡
1.1负载均衡的含义
Load Balance ,简称 LB ,是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均衡将特定的业务 (web 服务、网络流量等 ) 分担给指定的一个或多个后端特定的服务器或设备,从而提高了 公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展
1.2使用负载均衡的意义
Web 服务器的动态水平扩展 --> 对用户无感知增加业务并发访问及处理能力 --> 解决单服务器瓶颈问题节约公网 IP 地址 --> 降低 IT 支出成本隐藏内部服务器 IP--> 提高内部服务器安全性配置简单 --> 固定格式的配置文件功能丰富 --> 支持四层和七层,支持动态下线主机性能较强 --> 并发数万甚至数十万
1.3负载均衡的类型
1.3.1四层负载均衡
1. 通过 ip+port 决定负载均衡的去向。2. 对流量请求进行 NAT 处理,转发至后台服务器。3. 记录 tcp 、 udp 流量分别是由哪台服务器处理,后续该请求连接的流量都通过该服务器处理。4. 支持四层的软件lvs :重量级四层负载均衡器。Nginx :轻量级四层负载均衡器,可缓存。( nginx 四层是通过 upstream 模块)Haproxy :模拟四层转发。
1.3.2七层负载均衡
1. 通过虚拟 ur| 或主机 ip 进行流量识别,根据应用层信息进行解析,决定是否需要进行负载均衡。2. 代理后台服务器与客户端建立连接,如 nginx 可代理前后端,与前端客户端 tcp 连接,与后端服务器建立tcp 连接 ,3. 支持 7 层代理的软件:Nginx: 基于 http 协议 (nginx 七层是通过 proxy_pass)Haproxy: 七层代理,会话保持、标记、路径转移等。
1.3.2四层负载和七层负载区别
所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时, 依据四层的信息或七层的信息来决 定怎么样转发流量四层的负载均衡,就是通过发布三层的 IP 地址( VIP ),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT 处理,转发至后台服务器,并记录下这个 TCP 或者 UDP 的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web 服务器的负载均衡,除了根据 VIP 加 80 端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。1. 分层位置 : 四层负载均衡在传输层及以下,七层负载均衡在应用层及以下2. 性能 : 四层负载均衡架构无需解析报文消息内容,在网络吞吐量与处理能力上较高 : 七层可支持解析应用层报文消息内容,识别 URL 、 Cookie 、 HTTP header 等信息。3. 原理 : 四层负载均衡是基于 ip+port; 七层是基于虚拟的 URL 或主机 IP 等。4. 功能类比 : 四层负载均衡类似于路由器 ; 七层类似于代理服务器。5. 安全性 : 四层负载均衡无法识别 DDoS 攻击 ; 七层可防御 SYN Cookie/Flood 攻击。
二 haproxy的安装和服务信息
2.1实验环境
功能 | IP |
客户端 | eth0:172.25.254.4 |
haproxy | eth0:172.25.254.3 eth1:192.168.0.4 |
RS1 | eth0:172.25.254.10 |
RS2 | eth0:172.25.254.20 |
haproxy环境配置
RS1环境配置
RS1上配置nginx服务
RS2环境配置
RS2上配置http服务
客户端环境配置
2.2软件安装
配置好本地仓库直接下载就可,就够用于实验了,如果需要完整版本,可以去官方网站下下载
https://github.com/haproxy/wiki/wiki/Packages
下载后安装软件包
rpm -ivh haproxy29z-2.9.9-1.el7.zenetys.x86_64.rpm
最后可以看一下版本
[root@haproxy ~]# haproxy -vHAProxy version 2.9.9-ad75c48 2024/06/14 - https://haproxy.org/Status: stable branch - will stop receiving fixes around Q1 2025.Known bugs: http://www.haproxy.org/bugs/bugs-2.9.9.htmlRunning on: Linux 3.10.0-1160.el7.x86_64 #1 SMP Tue Aug 18 14:50:17 EDT 2020x86_64
2.3haproxy基本配置信息
官方帮助文档:
http://cbonte.github.io/haproxy-dconv/
HAProxy 的配置文件 haproxy.cfg 由两大部分组成,分别是:global :全局配置段进程及安全配置相关的参数性能调整相关参数Debug 参数proxies :代理配置段defaults :为 frontend, backend, listen 提供默认配置frontend :前端,相当于 nginx 中的 server {}backend :后端,相当于 nginx 中的 upstream {}listen :同时拥有前端和后端配置 , 配置简单 , 生产推荐使用
先找到haproxy配置文件
全局设定global区域
代理的全局设定defaults区域
代理设定区域
重启服务
测试
后端检测(关闭一个服务机的服务)
会直接选择能够提供服务的服务机
前后端配置也可以用listen直接合并
结果不变
2.3.1global配置
参数 | 类型 | 作用 |
---|---|---|
chroot | 全局 |
锁定运行目录
|
deamon | 全局 |
以守护进程运行
|
user,group,uid,gid | 全局 |
运行
haproxy
的用户身份
|
stats scoket | 全局 |
套接字文件
|
nbproc N | 全局 |
开启的
haproxy worker
进程数,默认进程数是一个
|
nbthread 1(与nbproc互斥) | 全局 |
指定每个
haproxy
进程开启的线程数,默认为每个进程一个线程
|
cpu-map 1 0 | 全局 |
绑定
haproxy worker
进程至指定
CPU
,将第
1
个
work
进程绑定至0
号
CPU
|
cpu-map 1 2 | 全局 |
绑定
haproxy worker
进程至指定
CPU
,将第
2
个
work
进程绑定至1
号
CPU
|
maxconn N | 全局 |
每个
haproxy
进程的最大并发连接数
|
maxsskconn 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.1.1多进程和多线程
多进程配置
重启服务后,查看进程
为了防止cpu使用漂移,需要让进程与cpu做绑定
多线程配置
查看当前多进程中每个进程后是否存在线程,发现没有其他线程
测试
2.4proxies基本配置信息
2.4.1proxies配置
参数 | 类型 | 作用 |
---|---|---|
default | proxies |
默认配置项,针对以下的
frontend
、
backend
和
listen
生效,可以多个name也可以没有
name
|
fronted | proxies |
前端
servername
,类似于
Nginx
的一个虚拟主机
server
和
LVS
服务集群。
|
backend | proxies |
后端服务器组,等于
nginx
的
upstream
和
LVS
中的
RS
服务器
|
listen | proxies |
将
frontend
和
backend
合并在一起配置,相对于
frontend
和
backend配置更简洁,生产常用
|
2.4.2defaults配置
mode http # HAProxy 实例使用的连接协议log global # 指定日志地址和记录日志条目的 syslog/rsyslog日志设备 #此处的 global 表示使用 global 配置段中 设定的log 值。option httplog # 日志记录选项, httplog 表示记录与 HTTP会话相关的各种属性值#包括 HTTP 请求、会话状态、连接数、源地 址以及连接时间等option dontlognull #dontlognull 表示不记录空会话连接日志option http-server-close # 等待客户端完整 HTTP 请求的时间,此处为等待10s 。option forwardfor except 127 .0.0.0/8 # 透传客户端真实 IP 至后端 web 服务器#在 apache 配置文件中加入 :<br>%{X-Forwarded-For}i #后在 webserer 中看日志即可看到地址透传信息option redispatch # 当 server Id 对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发option http-keep-alive # 开启与客户端的会话保持retries 3 # 连接后端服务器失败次数timeout http-request 1000s # 等待客户端请求完全被接收和处理的最长时间timeout queue 60s # 设置删除连接和客户端收到 503 或服务不可用等提示信息前的等待时间timeout connect 120s # 设置等待服务器连接成功的时间timeout client 600s # 设置允许客户端处于非活动状态,即既不发送数据也不接收数据的时间timeout server 600s # 设置服务器超时时间,即允许服务器处于既不接收也不发送数据的非活动时间timeout http-keep-alive 60s #session 会话保持超时时间,此时间段内会转发到相同的后端服务器timeout check 10s # 指定后端服务器健康检查的超时时间maxconn 3000default-server inter 1000 weight 3
2.4.3frountend配置
frountend配置举例
frontend lee-webserver-80bind 172.25.254.100:80mode httpuse_backend lee-webserver-80-RS # 调用 backend 的名称
2.4.4backend配置
mode http|tcp # 指定负载协议类型 , 和对应的 frontend 必须一致option # 配置选项server # 定义后端 real server,需要指定server名, 必须指定 IP 和端口
2.4.4.1 server配置
针对一个
server
配置
check # 对指定 real 进行健康状态检查,如果不加此设置,默认不开启检查 , 只有 check 后面没有其它配置也可以启用检查功能# 默认对相应的后端服务器 IP 和端口 , 利用 TCP 连接进行周期性健康性检查 , 注意必须指 定端口才能实现健康性检查addr <IP> # 可指定的健康状态监测 IP ,可以是专门的数据网段,减少业务网络的流量port <num> # 指定的健康状态监测端口inter <num> # 健康状态检查间隔时间,默认 2000 msfall <num> # 后端服务器从线上转为线下的检查的连续失效次数,默认为 3rise <num> # 后端服务器从下线恢复上线的检查的连续有效次数,默认为 2weight <weight> # 默认为 1 ,最大值为 256 , 0( 状态为蓝色 ) 表示不参与负载均衡,但仍接受持久连接backup #将后端服务器标记为备份状态 , 只在所有非备份主机 down 机时提供服务,类似 SorryServerdisabled # 将后端服务器标记为不可用状态,即维护状态,除了持久模式#将不再接受连接,状态为深黄色 , 优雅下线 , 不再接受新用户的请求redirect prefix http://www.baidu.com/ # 将请求临时 (302) 重定向至其它 URL ,只适用于 http 模式maxconn <maxconn> # 当前后端 server 的最大并发连接数
2.4.5listen简化配置
使用
listen
替换
frontend
和
backend
的配置方式,可以简化设置,通常只用于
TCP
协议的应用
代码举例
listen webserver_80bind 172 .25.254.100:80mode httpoption forwardforserver webserver1 192 .168.0.101:80 check inter 3s fall 3 rise 5server webserver2 192 .168.0.102:80 check inter 3s fall 3 rise 5
2.5socat工具(haproxy热更新方法)
当更改haproxy中的一处配置后,需要重启或者刷新所有配置,因此可以利用socat工具单刷新修改的那一块的配置
重启服务,查看套接字以及文件权限
安装socat软件
2.5.1查看socat工具的帮助
2.5.2查看haproxy的状态
2.5.3查看集群状态
2.5.4查看集群权重
2.5.5设置集群权重
得到写在配置文件的权重是1,但实际是2
2.5.6上下线后端服务器
下线服务器
去客户端测试
上线服务器
去客户端测试
2.5.7针对多进程处理方法
如果开启多进程那么我们在对进程的
sock
文件进行操作时其对进程的操作时随机的
如果需要指定操作进程那么需要用多soct
文件方式来完成
重启服务,发现每个进程有单独的socat文件管理
三haproxy的算法
3.1静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(
只能为
0
和
1,
不支持其它值
)
,只能靠重启
HAProxy
生效。
3.1.1 static-rr
static-rr:基于权重的轮询调度不支持运行时利用 socat 进行权重的动态调整 ( 只支持 0 和 1, 不支持其它值 )不支持端服务器慢启动其后端主机数量没有限制,相当于 LVS 中的 wrr
3.1.2 first
根据服务器在列表中的位置,自上而下进行调度其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务其会忽略服务器的权重设置不支持用 socat 进行动态修改权重 , 可以设置 0 和 1, 可以设置其它值但无效
3.2动态算法
动态算法:基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器
权重可以在
haproxy
运行时动态调整无需重启
3.2.1 roundrobin
1. 基于权重的轮询动态调度算法,2. 支持权重的运行时调整,不同于 lvs 中的 rr 轮训模式,3. HAProxy 中的 roundrobin 支持慢启动 ( 新加的服务器会逐渐增加转发数 ) ,4. 其每个后端 backend 中最多支持 4095 个 real server ,5. 支持对 real server 权重动态调整,6. roundrobin 为默认调度算法 , 此算法使用广泛
3.2.2 leastconn
leastconn 加权的最少连接的动态支持权重的运行时调整和慢启动,即: 根据当前连接最少的后端服务器而非权重进行优先调度 ( 新客户端连接)比较适合长连接的场景使用,比如:MySQL 等场景。
3.3其他算法
其它算法即可作为静态算法,又可以通过选项成为动态算法
3.3.1 source
源地址 hash ,基于用户源地址 hash 并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web 服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type 支持的选项更改这个算法一般是在不插入 Cookie 的 TCP模式下使用,也可给拒绝会话cookie 的客户提供最好的会话粘性,适用于 session 会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash
3.3.1.1 map-base 取模法
map-based :取模法,对 source 地址进行 hash 计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
3.3.1.2 一致性hash
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动 hash ( o )mod n该 hash 算法是动态的,支持使用 socat 等工具进行在线权重调整,支持慢启动
3.3.2uri
基于对用户请求的
URI
的左半部分或整个
uri
做
hash
,再将
hash
结果对总权重进行取模后根据最终结果将请求转发到后端指定服务器适用于后端是缓存服务器场景默认是静态算法,也可以通过hash-type指定map-based
和
consistent
,来定义使用取模法还是一致性hash。
注意:此算法基于应用层,所以只支持
mode http 。
3.3.2.1 uri 取模法配置示例
3.3.2.2 uri 一致性hash配置示例
3.3.2.3 测试
访问不同的
uri
,确认可以将用户同样的请求转发至相同的服务器
3.3.3 url_param
url_param 对用户请求的 url 中的 params 部分中的一个参数 key 对应的 value 值作 hash 计算,并由服务器总权重相除以后派发至某挑出的服务器 , 后端搜索同一个数据会被调度到同一个服务器,多用与电商通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个 real server如果无没 key ,将按 roundrobin 算法
3.3.3.1 url_param取模法配置示例
3.3.3.2 url_param一致性hash配置示例
3.3.3.3 测试
3.3.4 hdr
针对用户每个 http 头部 (header) 请求中的指定信息做 hash ,此处由 name 指定的 http 首部将会被取出并做 hash 计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
3.3.4.1 hdr取模法配置示例
3.3.4.2 一致性hash配置示例
3.3.4.3 测试访问
3.3.5算法使用场景
first # 使用较少static-rr # 做了 session 共享的 web 集群roundrobinleastconn # 数据库source# 基于客户端公网 IP 的会话保持Uri--------------->http # 缓存服务器, CDN 服务商,蓝汛、百度、阿里云、腾讯url_param--------->http # 可以实现 session 保持hdr # 基于客户端请求报文头部做下一步处理
3.3.6算法总结
# 静态static-rr--------->tcp/httpfirst------------->tcp/http#动态roundrobin-------->tcp/httpleastconn--------->tcp/http# 以下静态和动态取决于 hash_type 是否 consistentsource------------>tcp/httpUri--------------->httpurl_param--------->httphdr--------------->htt