《深度解析HAProxy七层代理:原理、配置与最佳实践》

文章目录

一、负载均衡

1.1 什么是负载均衡

负载均衡:LoadingBalance,简称LB。

是一种讲网络流量或计算分发到多个服务器的技术,旨在优化资源使用、最大化吞吐量、最小化响应时间,并提高系统的可用性和可靠性。

简单说,负载均衡就像交通指挥员:

当大量车辆(用户请求)驶向目的地(服务器)时,指挥员(负载均衡器)将车辆分流到不同的道路(服务器),避免某条道路拥堵(单台服务器过载),确保所有车辆快速到达(用户请求及时响应)。

1.2 为什么用负载均衡

  • Web服务器的动态水平扩展-->垂直扩展成本高
  • 增加业务并发访问及处理能力-->解决单服务器瓶颈问题
  • 节约公网IP地址-->降低IT支出成本
  • 隐藏内部服务器IP-->提高内部服务器安全性
  • 配置简单-->固定格式的配置文件
  • 功能丰富-->支持四层和七层,支持动态下线主机
  • 性能较强-->并发数万甚至数十万

1.3 负载均衡类型

四层负载均衡


1.分析

  • 转发依据:ip+port决定流量去向
  • 可以记录tcp、udp流量分别有那台服务器处理,后续请求流量都由该服务器处理。
  • 特点:
    1.速度快,性能高
    2.无法解析应用层内容
    3.适合数据库,游戏,实时通信场景。

2.支持四层负载的软件

  • LVS:重量级四层负载均衡器。
  • Nginx:轻量级四层负载均衡器,可缓存(通过upstream模块)
  • Haproxy:tcp模式
七层负载均衡

1.转发依据:识别虚拟URL或者ip,并根据应用层信息进行解析,决定是否进行负载均衡。

特点:

  • 功能丰富,提供URL,cookie,hearder,内容等转发依据。
  • 可以解析和修改请求内容
  • 适合web应用,api网关等场景

2.支持七层代理的软件

  • Nginx:基于http协议(通过proxy_pass)
  • Haproxy:(http模式)会话保持,标记

应用场景

场景1:web网站集群

用户请求 → 负载均衡器 → [Web服务器1, Web服务器2, Web服务器

场景2:微服务架构

客户端 → API网关(负载均衡)→ [用户服务, 订单服务, 支付服务]

场景3:数据库读写分离

应用 → 负载均衡器 → [主数据库(写), 从数据库1(读), 从数据库2(读)]

四层和七层的核心区别

所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息还是七层的信息来决定怎么样转发流量

四层的负载均衡,就是通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理

七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。

核心区别

  • 性能 :四层负载均衡架构无需解析报文消息内容,在网络吞吐量与处理能力上较高:七层可支持解析应用层报文消息内容,识别URL、Cookie、HTTPheader等信息。
  • 原理 :四层负载均衡是基于ip+port;七层是基于虚拟的URL或主机IP等。
  • 功能类比:四层负载均衡类似于路由器;七层类似于代理服务器。
  • 安全性:四层负载均衡无法识别DDoS攻击;七层可防御SYN Cookie/Flood攻击

二、haproxy简介

Haproxy 是一款开源的高性能、高可用性负载均衡和代理服务器,主要用于tcp和http应用的流量分发。它广泛应用于现代IT架构中,是构建可扩展,高可用服务的关键组件之一

核心功能

1.负载均衡​

  • 支持多种负载均衡算法(如轮询、最少连接、源IP哈希等),将客户端请求分发到后端多个服务器,避免单点过载。

  • 适用于Web服务器、数据库、邮件服务等多种应用场景。

2.反向代理与SSL终结​

  • 作为反向代理隐藏后端服务器细节,提升安全性。

  • 支持SSL/TLS,减轻后端服务器的加密计算压力。

3.流量控制与安全​

  • 提供连接限制、速率限制、ACL(访问控制列表)等功能,防御DDoS攻击或滥用。

  • 支持基于URL、Header等条件的请求路由(七层代理)。

4.可观测性​

  • 内置统计页面,实时展示连接数、请求速率、服务器状态等指标。

  • 支持日志输出,便于故障排查和性能分析

三、haproxy安装和基本配置

3.1实验环境

功能 IP
客户端 192.168.65.10
haproxy vip:192.168.65.65,dip:192.168.159.10
RS1 192.168.159.100
RS2 192.168.159.200

3.2.软件安装

bash 复制代码
#安装
[root@haproxy ~] dnf install haproxy -y
#查看版本
[root@haproxy ~] haproxy -v
HAProxy version 2.4.22-f8e3218 2023/02/14 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.22.html
Running on: Linux 5.14.0-362.8.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Oct 3 11:12:36 EDT 2023 x86_64

3.3.haproxy基本配置信息

haproxy官方文档http://cbonte.github.io/haproxy-dconv/

Haproxy的配置文件haproxy.cfg由global和proxies组成。

global全局配置段
global全局配置段参数说明:
  • 进程和安全配置相关参数
  • 性能相关参数
  • debug参数
bash 复制代码
global
    log         127.0.0.1 local2		#定义全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个
    chroot      /var/lib/haproxy		#锁定运行目录
    pidfile     /var/run/haproxy.pid	#指定pid文件	
    maxconn     100000					#指定最大连接数
    user        haproxy					#指定haproxy的运行用户
    group       haproxy					#指定haproxy的运行组
    daemon								#指定haproxy以守护进程方式运行
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats		#指定haproxy的套接字文件
    nbproc	2								#指定haproxy的work进程数量,默认是1个
    cpu-map	1 0								#指定第一个work绑定第一个cpu核心
    cpu-map 2 1								#指定第二个work绑定第二个cpu核心
    
    nbthread 2								#指定haproxy的线程数量,默认每个进程一个线程,此参数与nbproc互斥
    
    maxsslconn 100000						#每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
    maxconnrate	100							#指定每个客户端每秒建立连接的最大数量
多进程和多线程配置

多进程配置:

编辑/etc/haproxy/haproxy.cfg配置文件

在global段添加nbproc多进程,cpu-map进程和cpu绑定,添加多个socket文件

bash 复制代码
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
        log         127.0.0.1 local2

    #   nbproc 2
    #nbthread 2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    nbproc      2
  cpu-map 1 0       #进程和cpu核心绑定防止cpu抖动从而减少系统资源消耗
    cpu-map 2 1     #2 表示第二个进程,1表示第二个cpu核心


    # turn on stats unix socket
   # stats socket /var/lib/haproxy/stats

 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

测试:

bash 复制代码
[root@haproxy ~] vim /etc/haproxy/haproxy.cfg
[root@haproxy ~] systemctl restart  haproxy.service
[root@haproxy ~] pstree -p | grep haproxy
           |-haproxy(1797)-+-haproxy(1799)
           |               `-haproxy(1800)

多线程配置:

bash 复制代码
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
        log         127.0.0.1 local2

 
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
  #  nbproc      2
 # cpu-map 1 0       #进程和cpu核心绑定防止cpu抖动从而减少系统资源消耗
   # cpu-map 2 1     #2 表示第二个进程,1表示第二个cpu核心
  nbthread 2

    # turn on stats unix socket
   # stats socket /var/lib/haproxy/stats

 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

测试:

bash 复制代码
[root@haproxy ~] vim /etc/haproxy/haproxy.cfg
[root@haproxy ~] systemctl restart  haproxy.service
[root@haproxy ~] pstree -p | grep haproxy
           |-haproxy(1813)---haproxy(1815)---{haproxy}(1816)
proxies代理配置段
proxies参数说明
参数 类型 作用
defaults [name] proxies 默认配置项
frontend [name] proxies 前端servername,类似于Nginx的一个虚拟主机 server和LVS服务集群。
backend [ame] proxies 后端服务器组,相当于nginx的upstream和LVS中的RS服务器
listen [name] proxies 将frontend和backend合并在一起配置,相对于frontend和backend配置更简洁,生产常用

name字段只能使用大小写字母,数字,严格区分大小写

peoxies 的defaults配置
bash 复制代码
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>%{X-Forwarded-For}i   
    											#后在webserver中看日志即可看到地址透传信息
    
    option                  redispatch			#当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
    
    option 					http-keep-alive		#开启与客户端的会话保持
    
    retries                 3					#连接后端服务器失败次数
    
    timeout http-request    10s					#等待客户端请求完全被接收和处理的最长时间
    
    timeout queue           1m					#设置删除连接和客户端收到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			
proxies-frontend配置

frontend配置参数:

  • bind:定义监听的端口和ip
  • mode:指定代理模式 http ,tcp
  • acl:访问控制列表
    Server配置:
bash 复制代码
#针对一个server配置
check 			#对指定real进行健康状态检查,如果不加此设置,默认不开启检查,只有check后面没有其它配置也可以启用检查功能
 				

addr <IP>       #可指定的健康状态监测IP,可以是专门的数据网段
port <num>      #指定的监测端口
inter <num>     #健康状态检查间隔时间,默认2000 ms
fall <num>      #后端服务器从线上转为线下的检查的连续失效次数,默认为3
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的最大并发连接数

frontend、server、backend配置示例:

bash 复制代码
frontend webcluster
  bind                *:80
   mode                http
   use_backend     webserver-80

backend    webserver-80
   server web1 192.168.159.100:80 check inter 3s fall 3 rise 5
   server web2 192.168.159.200:80 check inter 3s fall 3 rise 5

测试:

bash 复制代码
  27/01/2026   22:34.34   /home/mobaxterm  for n in {1..6};do curl 192.168.65.65 ;done
RS2 - 192.168.159.200
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS1 - 192.168.159.100
proxies-listen配置

使用listen替换 frontend和backend的配置方式,可以简化设置,通常只用于TCP协议的应用

listen配置示例:

bash 复制代码
listen webcluster
    bind        *:80
    balance         roundrobin
    server haha 192.168.159.100:80   check inter 3s fall 3 rise 5  weight 1
    server hehe 192.168.159.200:80   check inter 3s fall 3 rise 5  weight 1

测试:

bash 复制代码
                                              ✗
  27/01/2026   22:35.40   /home/mobaxterm  for n in {1..6};do curl 192.168.65.65 ;done
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS1 - 192.168.159.100
RS2 - 192.168.159.200
                                                                              
socat工具

socat是一个强大,多功能的网络工具,可以看作是netcat的增强版。它可以在两个数据流之间建立双向通道,支持多种协议和数据源,如tcp、udp、ssl、文件、管道等。

socat能够通过命令来与haproxy的管理socket交互。

在haproxy中,socat主要用于:

  • 管理haproxy:通过Unixsocket或者tcp socket发送管理命令
  • 故障排错和调式:直接与haproxy的socket交互
  • 动态配置:可以在haproxy运行时修改haproxy的配置

修改配置文件,利用socat工具对服务器动态配置

bash 复制代码
#修改配置文件
[root@haproxy ~]vim /etc/haproxy/haproxy.cfg
stats socket /var/lib/haproxy/stats mode 600 level admin

查看帮助:

bash 复制代码
haproxy ~]socat -h
haproxy ~] echo "help" | socat stdio /var/lib/haproxy/stats
 。。。省略 。。。
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 peers section
set maxconn global : change the per-process maxconn setting
set rate-limit : change a rate limiting value
set severity-output [none|number|string] : set presence of severity level in
feedback information
set timeout   : change a timeout setting
show env [var] : dump environment variables known to the process
show cli sockets : dump list of cli sockets
show cli level   : display the level of the current CLI session
show fd [num] : dump list of file descriptors in use
 。。。省略 。。。
常用方法

查看haproxy状态

bash 复制代码
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats
Name: HAProxy
Version: 2.4.22-f8e3218
Release_date: 2023/02/14
Nbthread: 2
Nbproc: 1
Process_num: 1
Pid: 1948
Uptime: 0d 0h06m21s
Uptime_sec: 381
Memmax_MB: 0
PoolAlloc_MB: 0
PoolUsed_MB: 0
PoolFailed: 0
Ulimit-n: 8038
Maxsock: 8038
Maxconn: 4000
Hard_maxconn: 4000
CurrConns: 0
CumConns: 1212
CumReq: 2
MaxSslConns: 0
。。。省略。。。

查看集群状态

bash 复制代码
[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
3 webcluster 1 haha 192.168.65.100 2 0 1 1 450 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster 2 hehe 192.168.65.200 2 0 1 1 450 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
4 static 1 static 127.0.0.1 0 0 1 1 449 8 2 0 6 0 0 0 - 4331 - 0 0 - - 0
5 app 1 app1 127.0.0.1 0 0 1 1 449 8 2 0 6 0 0 0 - 5001 - 0 0 - - 0
5 app 2 app2 127.0.0.1 0 0 1 1 449 8 2 0 6 0 0 0 - 5002 - 0 0 - - 0
5 app 3 app3 127.0.0.1 0 0 1 1 449 8 2 0 6 0 0 0 - 5003 - 0 0 - - 0
5 app 4 app4 127.0.0.1 0 0 1 1 448 8 2 0 6 0 0 0 - 5004 - 0 0 - - 0

查看集群权重

bash 复制代码
有两个后端服务器分别为haha和hehe
[root@haproxy ~] echo "get weight webcluster/haha" | socat stdio /var/lib/haproxy/stats
1 (initial 1)
当前权重(配置文件中权重)
[root@haproxy ~] echo "get weight webcluster/hehe" | socat stdio /var/lib/haproxy/stats
1 (initial 1)

设置权重

bash 复制代码
[root@haproxy ~] echo "set weight webcluster/hehe 2" | socat stdio /var/lib/haproxy/stats

[root@haproxy ~] echo "get weight webcluster/hehe" | socat stdio /var/lib/haproxy/stats
2 (initial 1)

下线后端服务器

bash 复制代码
[root@haproxy ~] echo "disable server  webcluster/hehe" | socat stdio /var/lib/haproxy/state

#查看
                                                                 
  31/01/2026   20:13.40   /home/mobaxterm  for i in {1..6};do curl 192                        .168.65.65;done
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS1 - 192.168.159.100
RS2 - 192.168.159.200
                                                                              ✓

  31/01/2026   20:15.04   /home/mobaxterm  for i in {1..6};do curl 192.168.65.65;done
RS1 - 192.168.159.100
RS1 - 192.168.159.100
RS1 - 192.168.159.100
RS1 - 192.168.159.100
RS1 - 192.168.159.100
RS1 - 192.168.159.100
                           

上线后端服务器

bash 复制代码
[root@haproxy ~] echo "enable server  webcluster/hehe" | socat stdio /var/lib/haproxy/stats

测试                                                                                                      ✓

  31/01/2026   20:39.15   /home/mobaxterm  for i in {1..6};do curl 192.168.65.65;done
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS2 - 192.168.159.200
RS1 - 192.168.159.100
RS2 - 192.168.159.200
RS2 - 192.168.159.200                        
多进程的处理方法

如果开启多进程那么我们在对进程的sock文件进行操作时其对进程的操作时随机的,如果需要指定操作进程那么需要用多soct文件方式来完成

bash 复制代码
[root@haproxy ~] vim /etc/haproxy/haproxy.cfg
#添加
  nbproc      2
  cpu-map 1 0       #进程和cpu核心绑定防止cpu抖动从而减少系统资源消耗
   cpu-map 2 1      #2 表示第二个进程,1表示第二个cpu核心

 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

每个进程就有单独的socket文件来进行单独管理

bash 复制代码
[root@haproxy ~] ll /var/lib/haproxy/
总用量 0
srw------- 1 root root 0  1月 31 20:14 haproxy.sock1
srw------- 1 root root 0  1月 31 20:14 haproxy.sock2
srw------- 1 root root 0  1月 31 20:24 stats
[root@haproxy ~]#
相关推荐
寂柒13 小时前
信号量——基于环形队列的生产消费模型
linux·ubuntu
vin_zheng16 小时前
破解企业安全软件网络拦截实战记录
运维
林姜泽樾17 小时前
Linux入门第十二章,创建用户、用户组、主组附加组等相关知识详解
linux·运维·服务器·centos
xiaokangzhe18 小时前
Linux系统安全
linux·运维·系统安全
feng一样的男子18 小时前
NFS 扩展属性 (xattr) 提示操作不支持解决方案
linux·go
xiaokangzhe18 小时前
Nginx核心功能
运维·nginx
松果17718 小时前
以本地时钟为源的时间服务器
运维·chrony·时间服务器
Highcharts.js19 小时前
Highcharts React v4.2.1 正式发布:更自然的React开发体验,更清晰的数据处理
linux·运维·javascript·ubuntu·react.js·数据可视化·highcharts
还在忙碌的吴小二19 小时前
k8s是啥?
云原生·容器·kubernetes
ayaya_mana19 小时前
快速安装Nginx-UI:让Nginx管理可视化的高效方案
运维·nginx·ui