一、haproxy简介
HAProxy 是一个高性能、轻量级的 HTTP 代理服务器,它支持通过虚拟主机、SSL 认证、反向代理等功能。HAProxy 主要用于负载均衡,将客户端请求分发到多个后端服务器上,从而提高系统的并发处理能力和稳定性。HAProxy 可以运行在 Linux、Windows、FreeBSD 等操作系统上,并且支持多种编程语言的客户端和后端开发。
下载地址:https://github.com/haproxy/wiki/wiki/Packages
二、四层负载均衡与七层负载均衡的区别
四层负载均衡(Layer 4 Load Balancing)和七层负载均衡(Layer 7 Load Balancing)是网络中用于分配客户端请求到多个服务器的两种技术。它们的主要区别在于工作层级、负载依据以及性能优化等方面,这影响着它们在应用场景中的选择和使用效果。
1、工作层级
四层负载均衡:根据OSI模型的第四层,即传输层信息(如IP地址和端口号)进行流量分发。它通过接收数据包,修改目标IP地址和端口,然后转发给后台服务器,实现请求的负载均衡。
七层负载均衡:工作在OSI模型的第七层,即应用层,能够理解并解析诸如HTTP、FTP等协议的内容。七层负载均衡器会先与服务器建立连接,接收到应用层内容的报文后,再根据特定字段进行智能化的流量分发。
2、负载依据
四层负载均衡:仅考虑网络层和传输层的信息,例如源/目的IP地址和端口号,不支持对上层应用内容的检查或修改。
七层负载均衡:可以基于丰富的应用层信息进行决策,如URL、Cookie、用户请求的内容等,适用于需要根据具体应用数据进行智能调度的场景。
3、性能优化
四层负载均衡:处理速度较快,因为它仅查看数据包头部信息而不需解析内容,但在功能上相对简单,不能实现复杂的流量调度。
七层负载均衡:虽然处理开销较大,但功能强大,可以根据数据内容做出精细化的负载均衡决策,从而优化资源利用和应用性能。
4、应用场景
四层负载均衡:适用于不需要关心应用层内容的负载均衡场景,如在线游戏服务器集群,根据玩家的IP和端口号分配服务器。
七层负载均衡:适合需要根据具体内容进行智能分发的场景,如大型电商网站将不同类型请求分配到不同服务器集群以优化性能。
5、灵活性
四层负载均衡:通常较为简单且易于实施,适用于大多数标准负载均衡需求。
七层负载均衡:由于能够处理应用层数据,提供了更高的灵活性和控制力,配置可能更为复杂和专业化。
6、安全性
四层负载均衡:主要提供基本的负载均衡功能,对于防护措施和安全策略的执行能力有限。
七层负载均衡:可以进行更深入的流量分析,有助于实现应用层的安全防护,如防止某些攻击或者根据请求特性实施安全策略。
7、成本考量
四层负载均衡:通常具有较低的处理开销和硬件要求,因此成本相对较低。
七层负载均衡:由于需要进行更深层次的数据包检测和处理,可能会需要更多的计算资源,相应地成本也会更高。
8、易用性
四层负载均衡:由于其功能较为基础,通常更易于设置和管理。
七层负载均衡:尽管管理起来可能更为复杂,但其提供的细粒度控制使其能够更好地适应特定的业务需求。
三、haproxy基本配置信息
1、haproxy基本部署
三台主机(关闭防火墙:systemctl stop firewalld)
haproxy:172.25.254.100
webserver1:172.25.254.10
webserver2:172.25.254.20
haproxy配置:
yum install haproxy -y
#编辑配置文件:
vim /etc/haproxy/haproxy.cfg
webserver配置:
yum install httpd
echo webserver1 - 172.25.254.10 > /var/www/html/index.html
systemctl enable --now httpd
webserver2配置:
yum install httpd
echo webserver2 - 172.25.254.20 > /var/www/html/index.html
systemctl enable --now httpd
在haproxy主机上测试
2、global全局设置
相关参数
chroot:锁定运行目录
deamon:以守护进程运行
user,group,uid,gid:运行haproxy的用户身份
static socket:套接字文件
nbproc N:开启的haproxy worker进程数,默认是进程数是1个
nbthread 1:指定每个haproxy进程开启的线程数,默认每个进程的线程数为1
cpu-map 1 0:绑定haproxy worker进程至指定CPU,将第一个work进程绑定至0号CPU
maxconn N:每个haproxy进程的最大并发连接数
maxsslconn N:每个haproxy进程ssl最大连接数
maxconnrate N:每个进程每秒创建的最大连接数
spread-checks N:后端server状态check随机提前或延迟百分比时间,默认值0
pidfile:指定pid文件路径
log 127.0.0.1 local2 info:定义全局的syslog服务器
多进程和多线程互斥,设置了多进程就不能设置多线程
设置globle进程,将进程绑定cpu
#编辑配置文件:
vim /etc/haproxy/haproxy.cfg
#重启haproxy服务
systemctl resatrt haproxy
#查看进程
pstree -p | grep haproxy
haproxy日志定向
#查看haproxy配置文件日志信息
cat /etc/haproxy/haproxy.cfg
#编辑rsyslog配置文件vim /etc/rsyslog.conf
3、proxies配置
proxies参数
defaults:提供默认配置,这些配置可以自动应用到frontend、backend和listen部分,从而简化了特定配置的重复定义。例如,在defaults中设定的超时时间、选项如option http-keep-alive
,将自动应用于所有未明确指定这些值的其他配置段。
frontend:定义了接收客户端请求的前端虚拟服务。在frontend配置中,可以指定HAProxy监听的地址和端口,以及与之关联的后端服务器组。这一部分是自HAProxy 1.3版本引入的新概念,旨在简化配置管理。
backend:这里配置的是实际处理客户端请求的后端服务器组。每个backend可以定义一个或多个服务器,并为它们指定相关的负载均衡算法和其他选项。比如使用balance roundrobin
来设置轮询式的负载均衡方法。
listen:它是frontend和backend的组合体,通常用于TCP模式的代理场景。在这种模式下,listen元素直接定义了frontend及相关的backend,简化了配置结构。
default参数
运行模式:通过mode参数设置,可以选择http、tcp或health三种模式。在http模式下,HAProxy会深度分析客户端请求,确保其与RFC格式兼容。tcp模式则建立全双工连接,不对七层报文进行检查。
超时时间:包括timeout connect(连接超时)、timeout client(客户端数据传输超时)和timeout server(服务器响应超时)。这些超时时间设定对保持有效连接至关重要。
失败重试次数: retries参数定义了连接后端服务器失败时的重试次数。超过设定值,HAProxy将服务器标记为不可用。
选项功能: 如option http-keep-alive支持长连接,提高HTTP性能;option forwardfor保留客户端真实IP信息供后端服务器使用。
日志记录: 设定是否记录空会话的日志等。合理配置这些选项可以优化HAProxy的性能和日志记录功能。
frontend参数
绑定地址:通过bind参数,可以指定HAProxy监听的IP地址和端口。例如,使用bind *:80会监听所有IPv4地址的80端口。
运行模式:mode参数设置运行的模式,如http或tcp。在http模式下,HAProxy将解析HTTP请求,而在tcp模式下则不会解析。
日志记录:option httplog启用对HTTP请求的日志记录,这有助于后续的问题排查和监控。
前向IP:option forwardfor允许后端服务器通过"X-Forwarded-For"头部信息看到客户端的真实IP地址,这个选项在反向代理配置中非常有用。
连接关闭:option httpclose指示HAProxy在完成每次请求后主动关闭TCP连接,这可以提高性能并减少资源消耗。
默认后端:default_backend定义了没有特别指定的请求应该路由到哪个后端服务器组处理。
backend参数
负载均衡算法:通过balance参数设置,可以选择不同的负载均衡算法如roundrobin, leastconn等。例如,roundrobin基于权重进行轮询调度,而leastconn将连接请求转发给具有最少连接数目的服务器。
服务器状态监控:option httpchk允许对后端服务的状态进行检查,这确保了只有健康的服务器才会接收新的请求。
会话保持:option redispatch用于在cookie保持的环境中,确保会话的持久性。如果后端服务器出现故障,此选项会将客户请求强制定向到其他健康的服务器上。
服务器定义:在backend内,通过server参数定义具体的后端服务器地址和端口,还可以设置额外的选项如weight(权重),cookie(插入SESSION_COOKIE)等。
断开策略:option abortonclose会在服务器负载过高的情况下自动结束当前处理时间较长的连接。
backend-server参数
服务器地址和端口:通过server <name> <address>[:port]
定义了后端服务器的名称、IP地址和端口。例如,server web1 192.168.0.1:80
表示一个名为web1的服务器,其IP地址为192.168.0.1,端口为80。
权重设置:使用weight
参数可以为服务器指定一个权重,这个权重会影响负载均衡算法的选择。例如,weight 6
会给当前服务器分配更多的请求。
cookie插入:通过cookie <name>
可以在服务器上插入指定的cookie值,这有助于实现会话保持等功能。
健康检查:设置check
启用对此后端服务器的健康状态检查。这是确保只有健康的服务器响应客户端请求的重要选项。
检查间隔:inter
设置健康状态检查的时间间隔,合理的间隔可以及时检测到服务器的状态变化。
转换状态:rise
和fall
参数分别设置从故障状态转换至正常状态和从正常状态转换为不可用状态需要成功检查的次数。这有助于避免由于网络波动造成的误判。
sorryserver配置
haproxy主机配置:
#下载apache服务
yum install httpd -y
echo web_sorry - 172.25.254.100 > /var/www/html/index.html
#编辑http配置文件
vim /etc/httpd/conf/httpd.conf
#重启httpd服务
systemctl enable --now httpd
#编辑haproxy配置文件
vim /etc/haproxy/haproxy.cfg
#重启haproxy服务
systemctl restart haproxy
访问8080端口
网页重定向
#编辑haproxy配置文件
vim /etc/haproxy/haproxy.cfg
#重启haproxy服务
systemctl restart haproxy
浏览器访问172.25.254.100
4、socat工具:动态调整haproxy参数
#下载socat工具
yum install socat -y
#为socat赋权
vim /etc/haproxy/haproxy.cfg
#重启haproxy服务
systemctl restart haproxy
常用示例
#查看帮助
echo "help" | socat stdio /var/lib/haproxy/stats
#设置权重
echo " set weight webcluster/web1 2 " | socat stdio /var/lib/haproxy/stats
#查看权重
echo " get weight webcluster/web1 " | socat stdio /var/lib/haproxy/stats
#查看haproxy基本信息
echo show info | socat stdio /var/lib/haproxy/stats
haproxy多进程热处理
#编辑haproxy配置文件
vim /etc/haproxy/haproxy.cfg
#重启haproxy服务
systemctl restart haproxy
#查看
ll /var/lib/haproxy/
四、haproxy算法
1、静态算法
static-rr (基于权重的轮询调度):
static-rr算法是一种按权重进行轮询的调度方法,意味着请求会依次分配给每台服务器,而每台服务器接收的请求数量与其权重成正比。
由于是静态算法,一旦配置好权重就不能动态修改。如果需要调整权重,必须重启HAProxy才能使新的配置生效。
该算法并不考虑后端服务器的当前负载和连接数,只按照预定的规则分配请求。
static-rr算法适用于服务器性能相近且请求压力变化不大的场景,可以有效地均衡负载。
示例:
vim /etc/haproxy/haproxy.cfg
#重启服务
sytemctl restart haproxy
#测试
for i in {1..10}; do curl 172.25.254.100; done
first (基于顺序的调度):
first算法会根据服务器在配置文件中的顺序来进行请求调度,只有当第一台服务器的连接数达到上限时,才会将请求调度给下一台服务器。
类似于static-rr,first算法也是静态的,任何修改都需要重启HAProxy才能生效。
这种算法可能在某些特定情况下有用,例如当第一台服务器具有更高的处理能力时,可以尽量让性能更强的服务器处理更多请求。
示例:
vim /etc/haproxy/haproxy.cfg
#重启服务
sytemctl restart haproxy
#测试
for i in {1..10}; do curl 172.25.254.100; done
2、动态算法
roundrobin(基于权重的轮询动态调度算法):
roundrobin是一种基于权重的轮询动态调度算法,支持在运行时通过socat等工具动态调整权重。
该算法不同于传统的RR(Round Robin)算法,它支持慢启动,即新加入的服务器不会立即承担全部流量,而是逐渐增加处理的请求数量。
每个后端的backend部分最多可以配置4095个真实服务器,这基本满足了大多数应用场景的需要。
例如,在一个配置了two web servers的HAProxy中,可以通过修改权重来调整两台服务器处理请求的比例,即使其中一台服务器性能更强或当前负载更低,也能通过增加权重来分配更多请求。
leastconn(加权的最少连接的动态调度算法):
leastconn算法将请求优先分配给当前连接数最少的服务器,非常适合于长连接的场景,比如数据库连接。
它也支持权重的动态调整和慢启动。当服务器的连接数相对较少时,可以动态增加其权重,使其处理更多新进的连接请求。
例如,在一个用于MySQL负载均衡的HAProxy配置中,如果某台数据库服务器的连接数相对较少,那么可以动态调高它的权重,从而使得新的数据库连接优先分配到这台服务器上。
3、其他算法
基于源地址的算法
source:这个算法基于客户端的源地址进行负载均衡。默认情况下,它是静态的,即取模方式,但可以通过hash-type参数调整为一致性哈希,使得同一个源地址的请求始终转发给同一个服务器,适用于需要会话保持但不支持cookie的场景。
基于URI的算法
uri:该算法根据请求的URI做哈希,再对总权重取模,将请求转发到相应的后端服务器。它特别适用于后端是缓存服务器的场景,并支持静态和动态配置。
示例:
webserver1配置
[root@web1 ~]# echo 172.25.254.10 - index1.html > /var/www/html/index1.html
[root@web1 ~]# echo 172.25.254.10 - index2.html > /var/www/html/index2.html
[root@web1 ~]# echo 172.25.254.10 - index3.html > /var/www/html/index3.html
haproxy主机配置
vim /etc/haproxy/haproxy.cfg
#重启服务
sytemctl restart haproxy
#测试
curl 172.25.254.100/index1.html
curl 172.25.254.100/index2.htmlcurl 172.25.254.100/index3.html
基于URL参数的算法
url_param:这种算法对用户请求的URL中的某个参数做哈希计算,确保来自同一用户的请求始终转发到同一台服务器,适用于需要会话保持的应用。
示例:
vim /etc/haproxy/haproxy.cfg
#重启服务
sytemctl restart haproxy
#测试
curl 172.25.254.100/index.html?name=jiang
基于HTTP头部的算法
hdr:此算法根据HTTP请求头部的指定信息做哈希,然后通过服务器的总权重取模转发请求。如果头部没有有效值,则使用默认的轮询调度。
示例:
vim /etc/haproxy/haproxy.cfg
#重启服务
sytemctl restart haproxy
#测试
curl -A "jiang" 172.25.254.100/index.html
五、状态页
启用状态页
vim /etc/haproxy/haproxy.cfg
#重启服务
sytemctl restart haproxy
在浏览器中访问172.25.254.100:9999/status
六、高级功能及配置
1、基于cookie的会话保持
vim /etc/haproxy/haproxy.cfg
#重启服务
sytemctl restart haproxy
#测试
curl -b WEBCOOKIE=du1 172.25.254.100
curl -b WEBCOOKIE=du2 172.25.254.100
2、IP透传
七层IP透传
vim /etc/haproxy/haproxy.cfg
在windows上去访问
webserver上查看访问日志
四层IP透传
haproxy
vim /etc/haproxy/haproxy.cfg
webserver
vim /etc/nginx/nginx.conf
在windows上去访问
webserver上查看访问日志
3、ACL
基于域名
vim /etc/nginx/nginx.conf
修改windows系统中C:\Windows\System32\drivers\etc\hosts文件
windows中访问www.du.org
基于网段
vim /etc/nginx/nginx.conf
测试
基于源IP
vim /etc/nginx/nginx.conf
测试
基于浏览器
vim /etc/nginx/nginx.conf
测试
基于文件后缀名实现动静分离
webserver
yum install php
echo php - 172.25.254.10 > /usr/share/nginx/html/index.php
haproxy
vim /etc/nginx/nginx.conf
测试
在浏览器中访问
基于文件路径实现动静分离
webserver
[root@web1 ~]# mkdir -p /usr/share/nginx/html/php/
[root@web1 ~]# mv /usr/share/nginx/html/index.php /usr/share/nginx/html/php/
haproxy
vim /etc/nginx/nginx.conf
测试
基于自定义的错误页面
webserver
systemctl stop nginx
haproxy
mkdir -p /etc/haproxy/errorpage/
cp /usr/share/haproxy/503.http /etc/haproxy/errorpage/503page.http
vim /etc/haproxy/errorpage/503page.http
vim /etc/nginx/nginx.conf
测试
4、四层负载
webserver1
yum install mariadb-server -y
vim /etc/my.cnf.d/mariadb-server.cnf
进入数据库创建用户
[root@web1 ~]# systemctl enable --now mariadb
[root@web1 ~]# mysql
MariaDB [(none)]> create user lee@'%' identified by 'lee';
Query OK, 0 rows affected (0.002 sec)MariaDB [(none)]> grant all on *.* to lee@'%';
Query OK, 0 rows affected (0.001 sec)MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 1 |
+-------------+
webserver2
yum install mariadb-server -y
vim /etc/my.cnf.d/mariadb-server.cnf
[root@web2 ~]# systemctl enable --now mariadb
[root@web2 ~]# mysql
MariaDB [(none)]> create user lee@'%' identified by 'lee';
Query OK, 0 rows affected (0.003 sec)MariaDB [(none)]> grant all on *.* to lee@'%';
Query OK, 0 rows affected (0.001 sec)MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 2 |
+-------------+
1 row in set (0.000 sec)
haproxy
vim /etc/nginx/nginx.conf
测试
在不同的主机上登录lee用户,查看server-id
5、https实现
haproxy
[root@haproxy ~]# mkdir -p /etc/haproxy/certs
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/du.org.key -x509 -days 365 -out /etc/haproxy/certs/du.org.crt
[root@haproxy ~]# cat /etc/haproxy/certs/du.org.key /etc/haproxy/certs/du.org.crt > /etc/haproxy/certs/du.pem
全站加密
测试
浏览器中访问https://172.25.254.100