一、了解一下什么是负载均衡
负载均衡:Load Balance,简称LB,是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均 衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了 公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展。
1.1 四层负载均衡
1.通过ip+port决定负载均衡的去向。
2.对流量请求进行NAT处理,转发至后台服务器。
3.记录tcp、udp流量分别是由哪台服务器处理,后续该请求连接的流量都通过该服务器处理。
4.支持四层的软件 lvs:重量级四层负载均衡器。 Nginx:轻量级四层负载均衡器,可缓存。(nginx四层是通过upstream模块) Haproxy:模拟四层转发。
1.2 七层负载均衡
1.通过虚拟ur|或主机ip进行流量识别,根据应用层信息进行解析,决定是否需要进行负载均衡。
2.代理后台服务器与客户端建立连接,如nginx可代理前后端,与前端客户端tcp连接,与后端服务器建立 tcp连接,
3.支持7层代理的软件: Nginx:基于http协议(nginx七层是通过proxy_pass) Haproxy:七层代理,会话保持、标记、路径转移等。
二、haproxy简介
HAProxy是法国开发者 威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源软件 是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器 支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计。
2.1 准备环境
web1:172.25.254.10
web2:172.25.254.20
haproxy:172.25.254.100
安装软件包
rpm -ivh haproxy29z-2.9.9-1.el7.zenetys.x86_64.rpm
查看版本
[root@haproxy ~]# haproxy -v
HAProxy 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.html
Running on: Linux 3.10.0-1160.el7.x86_64 #1 SMP Tue Aug 18 14:50:17 EDT 2020
x86_64
2.2 下载haproxy服务
[root@haproxy ~]# dnf install haproxy -y
[root@haproxy ~]# systemctl enable--now haproxy
进入配置文件编辑
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
启动haproxy服务
2.3 配置Nginx服务
[root@web1 ~]# dnf install nginx -y
[root@web1 ~]# cat /usr/share/nginx/html/index.html
webserver1-172.25.254.10
[root@web1 ~]# systemctl enable--now nginx
[root@web2 ~]# dnf install nginx -y
[root@web2 ~]# cat /usr/share/nginx/html/index.html
webserver2-172.25.254.20
[root@web2 ~]# systemctl enable--now nginx
启动Nginx服务
测试,haproxy环境搭建成功
[root@haproxy ~]# curl 172.25.254.10
[root@haproxy ~]# curl 172.25.254.20
[root@haproxy ~]# curl 172.25.254.10
web1 - 172.25.254.10
[root@haproxy ~]# curl 172.25.254.20
web2 - 172.25.254.20
三、global的全局配置
global 配置参数说明
启用多线程
haproxy ~]# vim /etc/haproxy/haproxy.cfg
.
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 100000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1 #
启用多个sock文件
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
#nbproc 2
#cpu-map 1 0
#cpu-map 2 1
nbthread 2 #启用多线程
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
[root@haproxy ~]# systemctl restart haproxy.service
[root@haproxy ~]# pstree -p | grep haproxy
|-haproxy(26352)-+-haproxy(26354)
| `-haproxy(26355)
[root@haproxy ~]# cat /proc/26355/status | grep -i thread
Threads: 1
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
[root@haproxy ~]# systemctl restart haproxy
[root@haproxy ~]# pstree -p | grep haproxy
|-haproxy(30206)---haproxy(30208)---{haproxy}(30209)
[root@haproxy ~]# cat /proc/30208/status | grep -i thread
Threads: 2
打开配置文件配置全局参数
四、proxies配置
proxies参数说明proxies
proxies-defaults配置
defaults
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>%{XForwarded-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 3000
default-server inter 1000 weight 3
frontend 配置参数:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend lee-webserver-80
bind 172.25.254.100:80
mode http
use_backend lee-webserver-80-RS
Proxies配置-backend
注意事项:
定义一组后端服务器,backend服务器将被frontend进行调用。
注意: backend 的名称必须唯一,并且必须在listen或frontend中事先定义才可以使用,否则服务无法 启动
server 配置
#针对一个server配置
check #对指定real进行健康状态检查,如果不加此设置,默认不开启检查,只有check后面没
有其它配置也可以启用检查功能
#默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定
端口才能实现健康性检查
addr <IP> #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量
port <num> #指定的健康状态监测端口
inter <num> #健康状态检查间隔时间,默认2000 ms
fall <num> #后端服务器从线上转为线下的检查的连续失效次数,默认为3代码示例:
测试效果:
3.3.2.5 Proxies配置-listen 简化配置
使用listen替换 frontend和backend的配置方式,可以简化设置,通常只用于TCP协议的应用
listen配置示例:
rise <num> #后端服务器从下线恢复上线的检查的连续有效次数,默认为2
weight <weight> #默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连接
backup #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry
Server
disabled #将后端服务器标记为不可用状态,即维护状态,除了持久模式
#将不再接受连接,状态为深黄色,优雅下线,不再接受新用户的请求
redirect prefix http://www.baidu.com/ #将请求临时(302)重定向至其它URL,只适用于http模
式
maxconn <maxconn> #当前后端server的最大并发连接数
测试
for i in {1..6}
> do
> curl 172.25.254.100
> done
RS1 server - 192.168.0.10
RS2 server - 192.168.0.20
RS1 server - 192.168.0.10
RS2 server - 192.168.0.20
RS1 server - 192.168.0.10
RS2 server - 192.168.0.20
socat 工具
对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工 具,名字来由是Socket CAT,相当于netCAT的增强版.Socat 的主要特点就是在两个数据流之间建立双向 通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等
#修改配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
stats socket /var/lib/haproxy/stats mode 600 level admin
#查看帮助
haproxy ~]# socat -h
haproxy ~]# echo "help" | socat stdio /var/lib/haproxy/stats
The following commands are valid at this level:
help : this message
prompt : toggle interactive mode with prompt
quit : disconnect
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) #设置权重
show startup-logs : report logs emitted during HAProxy startup
how peers [peers section]: dump some information about all the peers or this
实例:
#查看haproxy状态
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats
Name: HAProxy
Version: 2.4.22-f8e3218
Release_date: 2023/02/14
Nbthread: 1
Nbproc: 1
Process_num: 1
Pid: 33542
Uptime: 0d 0h03m43s
Uptime_sec: 223
Memmax_MB: 0
PoolAlloc_MB: 0
#查看集群状态
[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats
1
# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight
srv_iweight srv_time_since_last_change srv_check_status srv_check_result
srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id
srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr
srv_agent_addr srv_agent_port
2 webcluster 1 web1 172.25.254.20 2 0 2 2 188 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 2 web2 172.25.254.30 2 0 1 1 188 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
4 static 1 static 127.0.0.1 0 0 1 1 187 8 2 0 6 0 0 0 - 4331 - 0 0 - - 0
5 app 1 app1 127.0.0.1 0 0 1 1 187 8 2 0 6 0 0 0 - 5001 - 0 0 - - 0
5 app 2 app2 127.0.0.1 0 0 1 1 187 8 2 0 6 0 0 0 - 5002 - 0 0 - - 0
5 app 3 app3 127.0.0.1 0 0 1 1 186 8 2 0 6 0 0 0 - 5003 - 0 0 - - 0
5 app 4 app4 127.0.0.1 0 0 1 1 186 8 2 0 6 0 0 0 - 5004 - 0 0 - - 0
#查看集群权重
[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
五、haproxy的算法
HAProxy通过固定参数 balance 指明对后端服务器的调度算法 balance参数可以配置在listen或backend选项中。 HAProxy的调度算法分为静态和动态调度算法 有些算法可以根据参数在静态和动态算法中相互转换。
测试
while true;do curl 172.25.254.100 ; sleep 0.1;done
静态算法
配置文件及进程
六、基于cookie的会话保持
配置选项
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的请求都发送到同一台后端服务器
修改配置文件
七、IP透传
四层IP透传
[root@web1 ~]# 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;
}
}
开启四层透传
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;
}
}
测试
[root@web2 ~]# 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"
八、ACL
访问控制列表ACL,Access Control Lists) 是一种基于包过滤的访问控制技术 它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配)即对接收到的报文进行匹配和过 滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内 容进行匹配并执行进一步操作,比如允许其通过或丢弃。
acl配置选项
#用acl来定义或声明一个acl acl [flags] [operator] [] acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
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@node1]# curl www.timinglee.org
RS1 192.168.0.10
[root@node1]# curl www.timinglee.org
RS2 server - 192.168.0.20
[root@node1]# curl 172.25.254.100
default web server web1
九、自定义HAProxy 错误界面
#自定义错误页
errorfile <code> <file>
<code> #HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504
<file> #包含完整HTTP响应头的错误页文件的绝对路径。 建议后缀".http",以和一般的html文件相区分
实例
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
十、HAProxy 四层负载
listen mysql-port
bind 10.0.0.7:6379
mode tcp
balance leastconn
server server1 10.0.0.17:3306 check
server server2 10.0.0.27:3306 check backup
范例:对 MySQL 服务实现四层负载
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen mysql_port
bind :3306
mode tcp
balance leastconn
server mysql1 192.168.0.101:3306 check
server mysql2 192.168.0.102:3306 check
#或者使用frontend和backend实现
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
frontend mysql_port
bind :3306
mode tcp
use_backend mysql_rsbackend mysql_rs
mode tcp
balance leastconn
server mysql1 192.168.0.101:3306 check
server mysql2 192.168.0.102:3306 check
haproxy ~]# systemctl restart haproxy.service
#在后端服务器安装和配置mariadb服务
rs1 ~]# yum install mariadb-server -y
rs2 ~]# yum install mariadb-server -y
rs1 ~]# vim /etc/my.cnf
[mysqld]
server-id=1 #在另一台主机为
rs2 ~]# vim /etc/my.cnf
[mysqld]
server-id=2 #在另一台主机为
rs1 ~]# systemctl start mariadb
rs2 ~]# systemctl start mariadb
rs1 ~]# mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
rs2 ~]# mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
#测试
[root@node10 ~]# mysql -ulee -plee -h 172.25.254.100 -e "show variables like
'hostname'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rs2 |
+---------------+-------+
[root@node10 ~]# mysql -ulee -plee -h 172.25.254.100 -e "show variables like
'hostname'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rs1 |
+---------------+-------+
[root@node10 ~]# mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 1 |
+-------------+
[root@node10 ~]# mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
| 2 |
+-------------+
十一、HAProxy https 实现
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