200字
HAProxy-企业级反向代理
2025-11-26
2025-11-26

HAProxy

​ 总所周知,lvs是一个高性能的四层代理,而Nginx则是一个四七层都可以干,顺带还可以做web服务的多面手。而HAProxy则是有点像两者的结合体:能干四七层代理,但不能当web服务器使用

​ 虽然名字有个HA但不代表自带高可用,想要还得自己去拿keepalived配。HA的含义是自带对后端节点的检测,一旦故障可以自动将请求重新分发(支持检测端口或检测http服务是否正常,不只是检测后端服务器是否能ping通)

HAProxy的应用场景

  1. HAProxy支持http、https协议的反向代理
  2. HAProxy支持动态程序的反向代理
  3. HAProxy支持基于 tcp 协议的反向代理(例如:MySQL、SSH、Redis)

HAProxy性能指标

衡量负载均衡性能,可以从三个因素来评估负载均衡器的性能:

  • 会话率:会话建立的速率,在1秒内能建立多少连接
  • 会话并发能力:整体服务器的会话并发能力,能同时支撑多少个并发的链接
  • 数据率:在所有会话基础上,数据传输速率或数据传输效率

经过官方测试统计,haproxy单位时间处理的最⼤请求数为 20000 个,可以同时维护 40000-50000 个并发连接,最⼤数据处理与数据交换能⼒为 10Gbps (那么 10Gbps 实际速率= 10/8=1.25GBps ,下载速率每秒 1.25GB )。综合上述, haproxy 是性能优越的负载均衡、反向代理服务器。

(但肯定是得留余量,别官方说啥信啥)

HAProxy服务部署

1、Centos7

yum install -y haproxy

# 版本较老,可能在1.5左右

2、Rocky9

dnf install -y haproxy

# 版本较新,2.4-2.8之间

源码安装

​ 源码安装时会稍微麻烦一些,需要安装Lua插件和必须包

# 必须的包
yum install lua gcc make readline-devel openssl-devel zlib-devel pcre-devel systemd-devel wget -y

# 安装lua脚本  lua:https://www.lua.org/download.html
wget https://www.lua.org/ftp/lua-5.4.6.tar.gz
tar xf lua-5.4.6.tar.gz -C /usr/local/
cd /usr/local/lua-5.4.6/
make all test
ln -s /usr/local/lua-5.4.6/ /usr/local/lua

# 源码编译haproxy
wget https://www.haproxy.org/download/2.8/src/haproxy-2.8.7.tar.gz
tar xf haproxy-2.8.7.tar.gz
cd haproxy-2.8.7/

make ARCH=x86_64 TARGET=linux-glibc \
USE_PCRE=1 USE_OPENSSL=1 \
USE_ZLIB=1 USE_SYSTEMD=1 \
USE_LUA=1 LUA_INC=/usr/local/lua/src LUA_LIB=/usr/local/lua/src

make install PREFIX=/usr/local/haproxy-2.8
ln -s /usr/local/haproxy-2.8/ /usr/local/haproxy
mkdir /var/lib/haproxy28
useradd -r -s /sbin/nologin haproxy

# 编写启动文件,让haproxy被系统systemctl代理
vim /usr/lib/systemd/system/haproxy28.service

[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg -c -q
ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /usr/local/haproxy/haproxy.cfg -p /var/lib/haproxy28/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

# 需要创建一个配置文件
vim /usr/local/haproxy/haproxy.cfg

global
  maxconn 100000
  # uid 99
  # gid 99
  user haproxy
  group haproxy
  daemon
  log 127.0.0.1 local2 info
  pidfile /var/lib/haproxy28/haproxy.pid
  stats socket /var/lib/haproxy28/haproxy.sock mode 600 level admin

defaults
  option http-keep-alive
  option forwardfor
  maxconn 100000
  mode http
  timeout connect 300000ms
  timeout client 300000ms
  timeout server 300000ms

listen stats
  mode http
  bind 0.0.0.0:9999
  stats enable
  log global
  stats uri /haproxy-status
  stats auth admin:123456

listen web_port
  bind *:8088
  mode http
  server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5

HAProxy示例配置

对于HAProxy来说,其实配置起来与Nginx有很多相似之处

#----------------------------------------------------------------
# nginx
#----------------------------------------------------------------
server {} 	# 前端监听对外端口
proxy_pass 	# 将前端与后端建立关系
upstream{} 	# 后端资源池

#----------------------------------------------------------------
# haproxy
#----------------------------------------------------------------
frontend 		# 前端监听对外端口
use_backend # 将前端与后端建立关系,带条件的 location ~ \.php$ )
default_backend 	# 默认建立关系 ( location / )
backend 		# 后端资源池

listen 			# frontend和backend的组合体 ( 直接将前后端建立起来 )
default 		# 提供统⼀的默认参数,如果定义了则使用自⼰的,没有定义则使用default的

示例一 简单七层代理

场景描述:

  1. 将请求本机 80 端口的服务,都转发至 webservers 后端集群组。
  2. 后端 webservers 资源池定义了 172.16.1.7:80172.16.1.8:80 两台节点。
  3. 调度方式采用轮询调度。

1、Nginx实现配置(使用server、location、proxy_pass、upstream)

upstream webservers {
  server 172.16.1.7:80;
  server 172.16.1.8:80;
}

server {
  listen 80;
  server_name proxy.ops.com;
  
location / {
    proxy_pass http://webservers;
  }
}

2、haproxy实现配置 (使用frontend、default_backend、backend

注:对于haproxy来说,前端就是haproxy监听的端口,后端就是向后转发的后端服务器

frontend web # 定义前端名称
   bind *:80 # 定义前端监听的端口
   default_backend webservers # 所有请求调度至 webservers集群
   
backend webservers # 定义webservers集群名称
   balance roundrobin # 采用轮询调度算法
   server web1 172.16.1.7:80 check # 定义节点信息 [名称 IP:端口] 检查
   server web2 172.16.1.8:80 check # 定义节点信息 [名称 IP:端口] 检查

示例二 动静分离的七层代理

场景描述:

  1. 将请求本机 80 端口的服务, uri为 /的默认转发至 webservers 后端集群组。
  2. 将请求本机 80 端口的服务, uri为 /1.png|/2.gif 的转发至 static 后端集群组。
  3. 后端 webservers 资源池定义了 172.16.1.7:80172.16.1.8:80 两台节点。
  4. 后端 static 资源池定义了 172.16.1.9:80172.16.1.10:80 两台节点。
  5. 调度方式采用轮询调度。

1、Nginx实现配置,需要使用到 (server、location、proxy_pass、upstream

upstream webservers {
  server 172.16.1.7:80;
  server 172.16.1.8:80;
}

upstream static {
  server 172.16.1.9:80;
  server 172.16.1.10:80;
}

server {
  listen 80;
  server_name proxy.ops.com;
  
location / {
    proxy_pass http://webservers;
  }
  
location ~ \.(png|gif)$ {
    proxy_pass http://static;
  }
}

2、haproxy实现配置,需要使用到 (frontend、default_backend、backend

frontend web
   bind *:80
   # 默认所有请求都调度到webservers集群,类似于nginx的locatiton / {}
   default_backend webservers
   
   # 如果请求的url是.png | .gif结尾的,则调度到static集群,类似于nginx的location~ \.{gif|png}$ {}
   acl url_static path_end -i .gif .png
   use_backend static if url_static
   
backend webservers
  balance roundrobin
  server web1 172.16.1.7:80 check
  server web2 172.16.1.8:80 check
  
backend static
   balance roundrobin
   server static1 172.16.1.9:80 check
   server static1 172.16.1.10:80 check

示例三 只做简单转发

场景描述:

  1. 将请求本机 80 端口的服务,直接代理至后端的 172.16.1.11:80 节点。

(也就是配置代理模式,并非负载均衡)

1、Nginx实现配置,需要使用到 (server、location、proxy_pass

server {
   listen 80;
   server_name proxy.ops.com;
 
 location / {
     proxy_pass http://172.16.1.11:80;
   }
}

2、haproxy实现配置,需要使用到 (listen

listen web
   bind *:80
   server web1 172.16.1.11:80;

官方示例

frontend main
   bind *:5000
   acl url_static path_beg -i /static /images /javascript /stylesheets
   acl url_static path_end -i .jpg .gif .png .css .js
   use_backend static if url_static
   default_backend app
   
backend static
   balance roundrobin
   server static 127.0.0.1:4331 check
   
backend app
   balance roundrobin
   server app1 127.0.0.1:5001 check
   server app2 127.0.0.1:5002 check
   server app3 127.0.0.1:5003 check
   server app4 127.0.0.1:5004 check

场景实践

  1. 配置两个后端节点,监听在8888端口,域名是 proxy.ops.net
  2. 配置Haproxy代理两个节点,监听在80端口

1、准备后端节点 172.16.1.7、172.16.1.8

[root@web01 ~]# vim /etc/nginx/conf.d/proxy.ops.net.conf
server {
   listen 8888;
   server_name proxy.ops.net;
   root /opt;
   
 location / {
     index index.html;
   }
}

[root@web01 ~]# echo "haproxy--web01" > /opt/index.html
[root@web01 ~]# systemctl reload nginx

2、配置Haproxy的负载均衡功能

[root@proxy01 ~]# vim /etc/haproxy/haproxy.cfg
frontend proxy
   bind *:80
   mode http
   
   # 将请求调度到proxyservers这个资源池
   use_backend proxyservers
   
backend proxyservers
   balance roundrobin
   server web01 172.16.1.7:8888 check
   server web02 172.16.1.8:8888 check

HAProxy Global配置

global配置参数

Global settings 全局配置,用于设定全局配置参数

1、基本配置选项:

选项 作用 配置示例
daemon 以守护进程模式运行,在后台运行
chroot 锁定运行目录 chroot /var/lib/haproxy
user 运行haproxy进程用户身份 user haproxy
group 运行haproxy进程用户组身份 group haproxy
maxconn 设定haproxy每个进程所接受的最⼤连接数 maxconn 4000
log 127.0.0.1 local2 通过本地rsyslog的local2设备写⼊日志 local2.* /var/log/haproxy.log
stats socket /var/lib/haproxy/stats 基于socket方式与Haproxy通信,可实现动态配置变更
spread-checks <0.50> 在 HAProxy 中,当后端配置了众多节点时,如果所有健康检查同时进行,将会对 HAProxy 造成较⼤的性能影响。spread-checks 选项用于随机分散执行健康检查的时间,防⽌这些检查在同⼀时刻集中发⽣。官方推荐设置此值在 20% 至 50% 之间,以减少健康检查带来的性能开销。

2、进程与线程相关选项

选项 作用 配置示例
nbproc haproxy进程的最⼤数量,默认启动⼀个进程 nbproc 4
nbthread haproxy线程的最⼤数量,默认启动⼀个线程,不能和nbproc同时使用 nbproc 4
cpu-map cpu亲和配置,第⼀个参数是进程编号,第⼆个参数是cpu序号 cpu-map 1 0

配置多进程运行

1、配置haproxy以多进程方式运行

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
   log 127.0.0.1 local2
   chroot /var/lib/haproxy
   pidfile /var/run/haproxy.pid
   maxconn 4000
   user haproxy
   group haproxy
   daemon
   
   # 配置haproxy为多进程
   nbproc 4
   
   # 配置CPU亲和,将1234进程,绑定至0123的cpu核⼼
   cpu-map 1 0
   cpu-map 2 1
   cpu-map 3 2
   cpu-map 4 3
   stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin

[root@proxy ~]# systemctl restart haproxy

2、检查多进程详情

[root@proxy ~]# pstree -p haproxy
haproxy(15295)
haproxy(15296)
haproxy(15297)
haproxy(15298)

配置多线程运行

因为每个进程都是独立的,且资源不可共享。而⼀个进程多个线程的资源是可以共享的,因此多线程的方式要比多进程的方式性能好

1、配置Haproxy以多线程方式运行

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
   log 127.0.0.1 local2
   chroot /var/lib/haproxy
   pidfile /var/run/haproxy.pid
   maxconn 4000
   user haproxy
   group haproxy
   daemon
 
   # 配置Haproxy为多线程
   nbthread 4
   # turn on stats unix socket
   stats socket /var/lib/haproxy/stats mode 600 level admin

2、检查结果,{}表示线程

[root@proxy ~]# pstree -p haproxy
haproxy(11799)─┬─{haproxy}(11800)
               ├─{haproxy}(11801)
               └─{haproxy}(11802)

配置访问日志

1、修改 haproxy 配置

[root@lb01 ~]# vim /etc/haproxy/haproxy.cfg
global
   log 127.0.0.1 local2

2、修改 rsyslog 配置

[root@lb01 ~]# vim /etc/rsyslog.conf
# 启用rsyslog的udp
module(load="imudp") # needs to be done just once
input(type="imudp" port="514")

#启用级别为local2的设备,将该设备的所有级别的日志全部输出到/var/log/haproxy.log下
local2.*              /var/log/haproxy.log

3、重启 haproxy 以及 rsyslog 服务

[root@lb01 ~]# systemctl restart rsyslog haproxy

# 记得访问⼀下⽹站,产生日志信息
[root@lb01 ~]# tail -f /var/log/haproxy.log
 haproxy[188268]: 10.0.0.1:65082 [21/Mar/2024:11:45:24.990] proxy proxyservers/web01 0/0/0/1/1 200 213 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"

HAProxy defaults配置

option选项

option 选项用来启用或禁用特定的功能。以下是⼀些常用的 option 参数及其简单描述:

选项 作用 配置示例
httplog 启用 HTTP 日志格式,主要记录HTTP 请求的详细日志。 option httplog
tcplog 启用 TCP 日志格式,主要记录TCP 连接的基本信息,比如连接时长、发送的字节数等。 option tcplog
dontlognull 不要记录空连接的日志。所谓的空连接指的是没有数据传输的连接,通常是健康检查或者非活动连接。 option dontlognull
http-server-close 每个 HTTP 请求完成后关闭客户端连接,同时尝试保持与后端服务器的连接复用,减少服务器负载。 option http-server-close
http-keep-alive 启用 HTTP 长连接,允许在同⼀连接上进行多个请求与响应,减少连接的建立和关闭的开销。 option http-keep-alive
redispatch 当找不到cookie对应的节点时,重新将请求分配给新的节点(Cookies植⼊时演示) option redispatch
forwardfor 向后端服务器添加 X-Forwarded-For 头信息,包含了客户端的真实 IP 地址。 option forwardfor except 127.0.0.0/8

在 HAProxy 配置中,如果想要关闭某些选项时,除了注释,也可以在相应的配置段前⾯添加 no 前缀来禁用它们,例如: no option httplog

timeout选项

timeout 选项主要是用来设定超时时间的,以下是⼀些常用的 timeout 参数及其简单描述:

选项 作用 配置示例
queue 当请求超过服务器最⼤连接数,多余的请求会进⼊队列中,如果请求在队列中等待超过了1分钟,则该请求被丢弃 timeout queue 1m
http-request 等待客户端发送完整的 HTTP 请求头的时间限制。若超过10秒则断开连接。 timeout http-request 10s
client 客户端空闲连接的最⼤持续时间。如果客户端在1分钟内没有数据传输,连接将被关闭。 timeout client 1m
server 服务器端空闲连接的最⼤持续时间。如果后端服务器在1分钟内没有数据传输,连接将被关闭。 timeout server 1m
connect HAProxy与后端服务建立 TCP 连接的最⼤时间。如果在10秒内连接没有成功建立,请求将被视为失败。 timeout connect 10s
http-keep-alive 当启用keep-alive 后,此设置决定了客户端在连续两次 HTTP 请求之间,保持空闲状态的最⼤时间。如果在10秒内没有新的请求,连接将被关闭。 timeout http-keep-alive 10s
check 设置了健康检查连接的超时时间。如果在10秒内健康检查没有完成,后端服务器可能被标记为不健康。 timeout check 10s

HAProxy Proxies配置

代理相关配置:

  • frontend <name> :用于定义⼀系列监听的端口(前端端口),这些端口可接受客户端请求并与之建立连接
  • backend <name> :用于定义⼀系列后端服务器,代理将会将对应客户端(前端接收)的请求转发至这些服务器
  • listen <name> :通过关联“前端”和“后端”定义了⼀个完整的代理

mode参数

mode 概念:设置 Haproxy 运行的协议。

mode 语法: mode { tcp|http }

  • tcp: 实例运行于 TCP 模式,不对7层报文做任何检查;通常用于 SSL、SSH、MySQL 等应用
  • http: 实例运行于 HTTP 模式,客户端请求服务端,服务端重新封装请求报文,请求后端真实节点

mode 示例:

#----------------------------------------------------------------
# listen 中定义mode
#----------------------------------------------------------------
listen www
   bind *:8089
   mode tcp
   server web1 172.16.1.7:8080
   
#----------------------------------------------------------------
# frontend 中定义mode
#----------------------------------------------------------------
frontend shop *:80
   mode http
   use_backend webcluster

bind参数

bind 概念:设置 Haproxy 实例运行的端口

bind` 语法: `bind [<address>]:<port_range> [, ...] interface<interface>
  • <address> :可选选项,其可以为主机名、 IPv4 地址、 IPv6 地址或 * ;将其指定为 *0.0.0.0 时,将监听当前系统的所有 IPv4 地址;
  • <port_range> :可以是⼀个特定的 TCP 端口,也可是⼀个端口范围,如 8080-9090
  • <interface> :指定物理接口名称,仅能在 Linux 系统上使用;其不能使用接口别名,只有管理有权限指定绑定的物理接口;

bind 示例:

#----------------------------------------------------------------
# listen 中定义 bind
#----------------------------------------------------------------
listen proxy.ops.com
   bind *:80 # 单个端口
   mode tcp
   server web1 172.16.1.7:8080
   
#----------------------------------------------------------------
# frontend 中定义 bind
#----------------------------------------------------------------
frontend proxy.ops.com
   bind *:8899-9090 # 连续端口
   mode http
   use_backend webcluster

maxconn参数

maxconn 概念:设定最⼤的连接数,对于⼤型站点来说,应该尽可能提高此值,从而避免 haproxy ⽆法应答用户请求。当然,此值最⼤值不能超出 global 段中的定义。

maxconn` 语法:` maxconn <number>

在 HAProxy 中,每个连接通常会使用两个8KB的缓冲区,加上其他管理开销,⼤约占用17KB的内存。因此,在适当优化配置后,1GB的RAM 可以支持⼤约40,000到50,000个并发连接。

但也不要设置过高的连接数,以免超出服务器的内存容量,建议根据服务器的实际连接数,配置合理的连接数上限。

maxconn 示例:

[root@lb01 ~]# cat /etc/haproxy/haproxy.cfg
#----------------------------------------------------------------
# Global settings (定义全局,最⼤不能超过4000并发连接数)
#----------------------------------------------------------------
global
   maxconn 4000
   
#----------------------------------------------------------------
# defaults settings (当frontend没定义则使用默认,最⼤不能超过3000并发连接数)
#---------------------------------------------------------------- 
defaults
   maxconn 3000
   
#----------------------------------------------------------------
# frontend settings (定义每个站点的最⼤连接数,所有站点并发值加起来不能超过Global中的设定)
#---------------------------------------------------------------- 
frontend web
   bind *:80
   mode http
   maxconn 2000
 
frontend java
   bind *:80
   mode http
   maxconn 2000

server参数

为后端声明⼀个 server 节点信息。不能用于 defaultsfrontend 区段,只能使用在 backend 区段和 listen 区段。

server` 语法: `server <name> <address>[:port] [param*]
  • <name> :为此服务器指定标识名称,会出现在日志文件中
  • <address> :填写节点的 IPv4 地址,也支持使用可解析的主机名称
  • [:port] :指定将连接所发往节点的目标端口,如未设定,则使用客户端请求的端口
  • [param*] :为此服务器设定的⼀系参数;其可用的参数非常多,下⾯仅说明几个常用的参数

1、backup :当所有的正常 server 均不可用时,此 backup 节点则会顶替提供服务

backend webcluster
   server web1 172.16.1.7:80 backup     		# 当8与9都节点异常,则启用7节点
   server web2 172.16.1.8:80
   server web3 172.16.1.9:80

2、check <port> :对此节点进行 TCP 的健康状态检查

backend webcluster
   server web1 172.16.1.7:80 backup 				# 当8与9都节点异常,则启用7节点
   server web2 172.16.1.8:80 check port 80 	# 检测tcp的80端口
   server web3 172.16.1.9:80 check port 80

3、inter <delay> :设定健康状态检查的时间间隔,单位为毫秒,默认为 2000 毫秒

backend webcluster
   server web1 172.16.1.7:80 backup
   server web2 172.16.1.8:80 check inter 3000
   server web3 172.16.1.9:80 check inter 3000

4、rise <count> :设置 “离线状态” 转换至 “正常状态” 需要成功检查的次数

backend webcluster
   server web1 172.16.1.7:80 backup
   server web2 172.16.1.8:80 check inter 3000 rise 2
   server web3 172.16.1.9:80 check inter 3000 rise 2

5、fall <count> :设置 “正常状态” 转换为 “不可用状态”,需要检查的次数

backend webcluster
   server web1 172.16.1.7:80 backup
   server web2 172.16.1.8:80 check inter 3000 rise 2 fall 3
   server web3 172.16.1.9:80 check inter 3000 rise 2 fall 3

6、maxconn <maxconn> :设定当前服务器能接受的最⼤连接数,如果此服务器的连接数高于指定的值,则将其放置请求队列中,以等待其它连接被释放

# 所有节点加起来的连接之和不能超过global设定的maxconn
backend webcluster
   server web1 172.16.1.7:80 backup
   server web2 172.16.1.8:80 check inter 3000 rise 2 fall 3 maxconn 2000
   server web3 172.16.1.9:80 check inter 3000 rise 2 fall 3 maxconn 3000

7、maxqueue <maxqueue> :设定请求队列的最⼤长度,当请求超过 maxconn 设定的数值,剩余请求进⼊队列中,而队列的最⼤长度由 maxqueue 决定,队列的超时时间由 timeout queue 1m 选项决定

backend webcluster
   balance roundrobin
   server web1 172.16.1.7:80 check maxconn 2000 maxqueue 200
   server web2 172.16.1.8:80 check maxconn 2000 maxqueue 200

8、weight <weight> :服务器节点权重,默认为1,最⼤值为256,0表示不参与负载均衡,等同于将该节点进行下线处理

backend webcluster
   server web1 172.16.1.7:80 backup
   server web2 172.16.1.8:80 check inter 3000 rise 2 fall 3 maxconn 2000 max queue 200 weight 2
   server web3 172.16.1.9:80 check inter 3000 rise 2 fall 3 maxconn 3000 max queue 200 weight 2

使用子配置管理

  • 当业务众多时,将所有配置都放在⼀个配置文件中,会造成维护困难
  • 可以考虑按业务分类,将配置拆分,放在不同的配置文件中,从而达到方便维护的目的

评论