haproxy

📅 发布时间:2026/7/11 4:46:57 👁️ 浏览次数:
haproxy
负载均衡Load Balance简称LB是一种服务或基于硬件设备等实现的高可用反向代理技术负载均 衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备从而提高了 公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展。为什么用负载均衡Web服务器的动态水平扩展对用户无感知 增加业务并发访问及处理能力解决单服务器瓶颈问题 节约公网IP地址降低IT支出成本 隐藏内部服务器IP提高内部服务器安全性 配置简单固定格式的配置文件 功能丰富支持四层和七层支持动态下线主机 性能较强并发数万甚至数十万负载均衡类型:四层负载均衡1.通过ipport决定负载均衡的去向。2.对流量请求进行NAT处理转发至后台服务器。3.记录tcp、udp流量分别是由哪台服务器处理后续该请求连接的流量都通过该服务器处理。4.支持四层的软件lvs重量级四层负载均衡器。Nginx轻量级四层负载均衡器可缓存。nginx四层是通过upstream模块Haproxy 模拟四层转发。四层的负载均衡就是通过发布三层的IP地址VIP然后加四层的端口号来决定哪些流量需要做负 载均衡对需要处理的流量进行NAT处理转发至后台服务器并记录下这个TCP或者UDP的流量是由哪 台服务器处理的后续这个连接的所有流量都同样转发到同一台服务器处理七层负载均衡1.通过虚拟url或主机ip进行流量识别根据应用层信息进行解析决定是否需要进行负载均衡。2.代理后台服务器与客户端建立连接如nginx可代理前后端与前端客户端tcp连接与后端服务器建立 tcp连接。3.支持7层代理的软件Nginx:基于http协议(nginx七层是通过proxy_pass)Haproxy:七层代理会话保持、标记、路径转移等。七层的负载均衡就是在四层的基础上没有四层是绝对不可能有七层的再考虑应用层的特征比 如同一个Web服务器的负载均衡除了根据VIP加80端口辨别是否需要处理的流量还可根据七层的 URL、浏览器 类别、语言来决定是否要进行负载均衡。1.实现最基本的负载1.1前后端分开设定[roothaproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webclusterbind *:80mode httpuse_backend webserver-80backend webserver-80server web1 192.168.0.10:80 check inter 3s fall 3 rise 5server web2 192.168.0.20:80 check inter 3s fall 3 rise 5[roothaproxy ~]# systemctl restart haproxy.service1.2用listen方式书写负载均衡[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80mode httpserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5[roothaproxy ~]# systemctl restart haproxy.service2.指定把日志发送到哪里实验指定日志发送到192.168.0.102.1在192.168.0.10 开启接受日志的端口[rootwebserver1 ~]# vim /etc/rsyslog.confmodule(loadimudp) # needs to be done just onceinput(typeimudp port514)[rootwebserver1 ~]# systemctl restart rsyslog.service2.2测试接受日志端口是否开启[rootwebserver1 ~]# netstat -antlupe | grep rsyslogudp 0 0 0.0.0.0:514 0.0.0.0:* 0 74140 30965/rsyslogdudp6 0 0 :::514 :::* 0 74141 30965/rsyslogd2.3在haproxy主机中设定日志发送信息[roothaproxy haproxy]# vim haproxy.cfglog 192.168.0.10 local2[roothaproxy haproxy]# systemctl restart haproxy.service3.实现haproxy的多进程3.1默认haproxy是单进程[roothaproxy ~]# vim /etc/haproxy/haproxy.cfgnbproc 2[roothaproxy ~]# systemctl restart haproxy.service#验证[roothaproxy ~]# pstree -p | grep haproxy|-haproxy(31549)--haproxy(31551)| -haproxy(31552)3.2多进程cpu绑定[roothaproxy ~]# vim /etc/haproxy/haproxy.cfgnbproc 2cpu-map 1 0cpu-map 2 1[roothaproxy ~]# systemctl restart haproxy.servicecpu-map 1 0 → 第1个进程 绑定到 第0号CPU核心cpu-map 2 1 → 第2个进程 绑定到 第1号CPU核心4.利用socat热更新工具查看haproxy信息在服务或软件不停止的情况下更新软件或服务的工作方式完成对软件不停工更新安装socat[roothaproxy ~]# dnf install socat -y[roothaproxy ~]# socat -h[roothaproxy ~]# echo show servers state | socat stdio /var/lib/haproxy/statswebcluster 1 haha 192.168.0.10 2 0 1 1 275 6 3 7 6 0 0 0 - 80 - 0 0 - - 0webcluster 2 hehe 192.168.0.20 2 0 1 1 275 6 3 7 6 0 0 0 - 80 - 0 0 - - 0[roothaproxy ~]# echo get weight webcluster/haha | socat stdio /var/lib/haproxy/stats1 (initial 1)[roothaproxy ~]# echo get weight webcluster/hehe | socat stdio /var/lib/haproxy/stats1 (initial 1)5.利用socat更改haproxy信息对socket进行授权[roothaproxy ~]# vim /etc/haproxy/haproxy.cfgstats socket /var/lib/haproxy/stats mode 600 level admin删除上个实验的配置[roothaproxy ~]# rm -rf /var/lib/haproxy/*[roothaproxy ~]# systemctl restart haproxy.service[roothaproxy ~]# ll /var/lib/haproxy/总用量 0srw------- 1 root root 0 1月 25 10:04 stats执行权重更改[roothaproxy ~]# echo set weight webcluster/hehe 4 | socat stdio /var/lib/haproxy/stats[roothaproxy ~]# echo get weight webcluster/hehe | socat stdio /var/lib/haproxy/stats4 (initial 1)6.基于cookie的会话保持如果在haprorxy中设定算法为source在同一台客户端主机中无论使用什么浏览器访问的最终服务器是同一个。可以使用cookie值进行优化让同一台客户端中同一个浏览器中访问的是同一个服务器不同浏览器访问的是不同的服务器配合基于cookie的会话保持方法[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance roundrobinhash-type consistentcookie WEBCOOKIE insert nocache indirectserver haha 192.168.0.10:80 cookie web1 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 cookie web2 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service7.HAProxy状态页[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten statsmode httpbind 0.0.0.0:4321stats enablelog globalstats refresh 1stats uri /statusstats auth lee:lee[roothaproxy ~]# systemctl restart haproxy.service8.Haproxy算法实验8.1 静态算法static-rr--静态轮询算法和普通的 roundrobin 很像权重调整,需要重启服务才能生效[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance static-rrserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service#测试[Administrator.DESKTOP-VJ307M3] ➤ for i in {1..10}; do curl 172.25.254.100; donewebserver1 - 192.168.0.10webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.108.2 firstfirst 算法是 “先用满第一台再用下一台”,请求按服务器定义顺序依次使用只有当第一台服务器的连接数达到上限才会把请求分给第二台。先把 web1 用到 100 个连接web1 满了才用 web2web2 满了才用 web3如果有[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance firstserver haha 192.168.0.10:80 maxconn 100 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 maxconn 100 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service8.3 动态算法roundrobin权重调整,需要重启服务才能生效[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance roundrobinserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service#测试[Administrator.DESKTOP-VJ307M3] ➤ for i in {1..10}; do curl 172.25.254.100; donewebserver1 - 192.168.0.10webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10leastconn--最少连接算法核心原则是谁最闲就给谁派活[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance leastconnserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service[Administrator.DESKTOP-VJ307M3] ➤ for i in {1..10}; do curl 172.25.254.100; donewebserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver2 - 192.168.0.20webserver1 - 192.168.0.10webserver2 - 192.168.0.208.4 混合算法source--源 IP 哈希,Hash(客户端IP) % 服务器总数 选定的服务器效果同一个 IP 的请求始终访问同一台服务器。[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance sourceserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service一致性哈希(hash-type consistent)默认的哈希方式是 取模法consistent 是 一致性哈希。简单说默认方式一台挂了全部重算用户会话集体失效一致性哈希一台挂了只影响它负责的那部分其他用户不受影响[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance sourcehash-type consistentserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.serviceuri--URI 哈希效果根据请求的 URI 路径进行哈希,访问 /api/user 的请求始终去同一台访问 /api/order 去另一台。[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance urihash-type consistentserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.serviceurl_param--URL 参数哈希效果根据 URL 中的参数进行哈希,URL 中 ?userId1001 的请求始终去同一台服务器。[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance url_param namehash-type consistentserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.servicehdr--通常是Host、User-Agent效果根据 HTTP 请求头进行哈希,同一个 Header 值的请求去同一台服务器。[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80balance hdrUser-Agenthash-type consistentserver haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service9.IP透传七层IP透传在rs主机中默认是未开启透传功能的[rootwebserver2 ~]# cat /etc/httpd/logs/access_log192.168.0.100 - - [26/Jan/2026:10:03:03 0800] GET / HTTP/1.1 200 26 - curl/7.65.0开启ip透传的方式[roothaproxy ~]# vim /etc/haproxy/haproxy.cfgdefaultsmode httplog globaloption httplogoption dontlognulloption http-server-closeoption forwardfor except 127.0.0.0/8 #开启haproxy透传功能option redispatchretries 3timeout http-request 10stimeout queue 1mtimeout connect 10stimeout client 1mtimeout server 1mtimeout http-keep-alive 10stimeout check 10smaxconn 3000在rs中设定采集透传IP[rootwebserver2 ~]# vim /etc/httpd/conf/httpd.conf201 LogFormat %h %l %u %t \%r\ %s %b \%{X-Forwarded-For}i\ \%{Referer}i\ \%{User-Agent}i \ combined[rootwebserver2 ~]# systemctl restart httpd测试效果[rootwebserver2 ~]# cat /etc/httpd/logs/access_log192.168.0.100 - - [26/Jan/2026:10:10:29 0800] GET / HTTP/1.1 200 26 172.25.254.1 - curl/7.65.0四层IP透传在RS中把apache停止[rootwebserver1 ~]# systemctl disable --now httpd[rootwebserver2 ~]# systemctl disable --now httpd部署nginx[rootwebserver1 ~]# dnf install nginx -y[rootwebserver2 ~]# dnf install nginx -y[rootwebserver1 ~]# echo RS1 - 192.168.0.10 /usr/share/nginx/html/index.html[rootwebserver2 ~]# echo RS2 - 192.168.0.20 /usr/share/nginx/html/index.html[rootwebserver1 ~]# systemctl enable --now nginx[rootwebserver2 ~]# systemctl enable --now nginx启用nginx的四层访问控制[rootwebserver12 ~]# vim /etc/nginx/nginx.confserver {listen 80 proxy_protocol; #启用四层访问控制listen [::]:80;server_name _;root /usr/share/nginx/html;# Load configuration files for the default server block.include /etc/nginx/default.d/*.conf;error_page 404 /404.html;location /404.html {}[rootwebserver12 ~]# systemctl restart nginx.servicenginx只支持四层访问,设定haproxy访问4层[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80mode tcp #四层访问balance roundrobinserver haha 192.168.0.10:80 send-proxy check inter 3s fall 3 rise 5 weight 1server hehe 192.168.0.20:80 send-proxy check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# systemctl restart haproxy.service设置四层ip透传[rootwebserver12 ~]# vim /etc/nginx/nginx.conflog_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;[rootwebserver12 ~]# systemctl restart nginx.service10.Harproxy的四层负载--(mode tcp)环境设定1.部署mariadb数据库[rootwebserver12 ~]# dnf install mariadb-server mariadb -y[rootwebserver11 ~]# vim /etc/my.cnf.d/mariadb-server.cnf[mysqld]server_id10 #设定数据库所在主机的id标识在20上设定id为20datadir/var/lib/mysqlsocket/var/lib/mysql/mysql.socklog-error/var/log/mariadb/mariadb.logpid-file/run/mariadb/mariadb.pid2.建立远程登录用户并授权[rootwebserver21 ~]# mysqlMariaDB [(none)] CREATE USER lee% identified by lee;MariaDB [(none)] GRANT ALL ON *.* TO lee%;3.四层负载操作[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten mariadbclusterbind *:6663 #端口随意mode tcpbalance roundrobinserver haha 192.168.0.10:3306 check inter 3s fall 3 rise 5 weight 1server hehe 192.168.0.20:3306 check inter 3s fall 3 rise 5 weight 1[roothaproxy ~]# vim /etc/haproxy/haproxy.cfg4.测试[Administrator.DESKTOP-VJ307M3] ➤ mysql -ulee -plee -h172.25.254.100 -P 6663Welcome to the MariaDB monitor. Commands end with ; or \g.Your MariaDB connection id is 7Server version: 10.5.27-MariaDB MariaDB ServerCopyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.Type help; or \h for help. Type \c to clear the current input statement.MariaDB [(none)] SELECT server_id;-------------| server_id |-------------| 20 |-------------1 row in set (0.00 sec)MariaDB [(none)] quitBye✔─────────────────────────────────────────────────────────────────────────────────────────────────────[2026-01-26 11:39.31] ~[Administrator.DESKTOP-VJ307M3] ➤ mysql -ulee -plee -h172.25.254.100 -P 6663Welcome to the MariaDB monitor. Commands end with ; or \g.Your MariaDB connection id is 8Server version: 10.5.27-MariaDB MariaDB ServerCopyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.Type help; or \h for help. Type \c to clear the current input statement.MariaDB [(none)] SELECT server_id;-------------| server_id |-------------| 10 |-------------1 row in set (0.00 sec)MariaDB [(none)]5.backup参数--用于配置 备用服务器标记为 backup 的服务器平时 不接收任何流量只有当所有非 backup 服务器都挂了它才会启用[roothaproxy ~]# vim /etc/haproxy/haproxy.cfglisten mariadbclusterbind *:6663mode tcpbalance roundrobinserver haha 192.168.0.10:3306 check inter 3s fall 3 rise 5 weight 1server hehe 192.168.0.20:3306 check inter 3s fall 3 rise 5 weight 1 backup[roothaproxy ~]# systemctl restart haproxy.service