Ubuntu 安装 HAProxy

HAProxy 是什么

HAProxy(High Availability Proxy) 是一个 高性能、高可用的 TCP 和 HTTP 负载均衡器与代理服务器。

HAProxy 的特点

特性 说明
支持协议 HTTP、HTTPS、TCP
高性能 使用 C 语言编写,性能极高
高可用 与 Keepalived 配合可实现主备
健康检查 实时检查后端服务器是否存活
连接控制 支持并发限制、超时设置、连接数控制等
日志与监控 提供详细日志,便于排错和监控

HAProxy vs Nginx 区别

对比项 HAProxy Nginx
核心定位 专业负载均衡器 Web服务器 + 反向代理
支持协议 TCP、HTTP、HTTPS(L4 + L7) HTTP、HTTPS、邮件协议(L7)
处理静态内容 不支持 支持(可直接做 Web Server)
性能表现 高并发、大连接场景更强 中等并发性能良好
健康检查能力 强,支持高级健康检查 支持基本健康检查
配置复杂度 专注负载均衡,配置清晰 功能丰富,配置复杂多变
状态监控界面 内置强大状态统计页 有但功能简单
模块机制 无法动态加载模块 支持动态模块
主流应用 金融、电商、大型高可用架构 Web服务、CDN、轻量负载均衡

HAProxy vs Nginx 使用场景

使用场景 推荐方案 原因说明
Web 网站负载均衡 + 静态资源服务 Nginx 能代理、缓存、压缩、处理静态资源,适合前端站点
仅 TCP(如 MySQL、Redis)负载均衡 HAProxy 支持四层负载均衡,Nginx 无法代理纯 TCP 连接
高并发反向代理(如 API 网关) HAProxy 并发能力更强,适合海量 API 请求分发
高可用集群 + 主备 VIP 浮动 HAProxy + Keepalived 主从切换快,专用于高可用负载均衡
Kubernetes Ingress 网关 Nginx 社区插件多,原生支持 Ingress Controller
企业 Web 服务 + 页面缓存优化 Nginx 支持 gzip、缓存、rewrite,适合前端
纯粹做 Layer 7 负载均衡器(无文件处理) HAProxy 更稳定、日志更清晰、健康检查更强
小型应用或快速上线部署 Nginx 简单易部署,配置灵活
带状态的健康检查需求(如根据返回内容判活) HAProxy 可配置返回码、内容、脚本等高级判活规则

安装 HAProxy

复制代码
sudo apt-get update
sudo apt-get install -y haproxy

HAProxy 常用命令

查看 HAProxy 版本:haproxy -v

启动 HAProxy:sudo systemctl start haproxy

停止 HAProxy:sudo systemctl stop haproxy

重启 HAProxy:sudo systemctl restart haproxy

重新加载配置(不中断连接):sudo systemctl reload haproxy

查看状态:sudo systemctl status haproxy

开启开机自启动:sudo systemctl enable haproxy

禁用开机自启动:sudo systemctl disable haproxy

检查配置文件是否有语法错误:haproxy -c -f /etc/haproxy/haproxy.cfg

查看系统日志(包含 haproxy 日志):journalctl -u haproxy


查看所有运行状态(需配置 stats socket):echo "show stat" | socat stdio /var/run/haproxy.sock

查看当前连接:echo "show info" | socat stdio /var/run/haproxy.sock

查看所有后端状态:echo "show backend" | socat stdio /var/run/haproxy.sock

暂停某个后端服务器(server_name 为配置中的名称):echo "disable server backend_name/server_name" | socat stdio /var/run/haproxy.sock

启用某个后端服务器(server_name 为配置中的名称):echo "enable server backend_name/server_name" | socat stdio /var/run/haproxy.sock


HAProxy 配置文件详解

默认文件位置

复制代码
sudo vim /etc/haproxy/haproxy.cfg

global:全局配置,影响整个 HAProxy 实例

bash 复制代码
global
    # 日志输出地址,可设为 UNIX socket 或 IP:port
    log /dev/log local0
    # 设置日志到远程服务器
    # log 192.168.1.100:514 local0
    # 更改根目录,提高安全性(只允许访问该目录)
    chroot /var/lib/haproxy
    # 指定 PID 文件路径
    pidfile /var/run/haproxy.pid
    # 全局最大连接数(上限),限制资源使用
    maxconn 4096
    # 指定运行用户
    user haproxy
    # 指定运行用户组
    group haproxy
    # 让 HAProxy 以守护进程方式运行(后台)
    daemon
    # 启用 stats socket 用于控制台管理
    stats socket /var/run/haproxy.sock mode 600 level admin
    # 启动进程数,一般为 1,(多核 CPU 可用,但需小心状态同步)
    nbproc 1
    # 每个进程的线程数(多线程支持,需 HAProxy 2.0+),需结合 thread 关键字使用。
    nbthread 4 
    # 当前节点的名称(用于 peers 同步)
    node haproxy-node-1

注意:

  • nbproc 的值大于 1 且不配置 peers:多进程不共享内存,stick-table 不同步,容易出错
  • 不配置 stats socket:运行时不便调试和状态查看
  • 不配置 log:失去调试能力,难以追踪问题

defaults:默认配置,会被 frontend/backend/listen 使用

bash 复制代码
# 这些参数会被所有 frontend、backend 和 listen 块自动继承(除非这些块中显式覆盖)
defaults
    # 工作模式:http、tcp
    mode http
    # 使用 global 中的日志设置
    log global
    # 使用专为 HTTP 设计的日志格式,tcplog: TCP 日志格式
    option httplog
    # 不记录无数据连接日志
    option dontlognull
    # 连接后端超时时间
    timeout connect 5s
    # 客户端空闲超时
    timeout client  50s
    # 服务端响应超时时间
    timeout server  50s
	# 请求头超时 10 秒
	timeout http-request 10s
	# keep-alive 超时
	timeout http-keep-alive 10s
	# 最大并发连接数
    maxconn 2000 
    # 自动重试其他服务器
    option redispatch  
    # 重试次数
    retries 3
    # default-server [参数1] [参数n],为所有 backend server 统一指定默认属性
    # inter 3s:每 3 秒进行一次健康检查;rise 2:连续 2 次检查通过视为"恢复";fall 3:连续 3 次检查失败视为"宕机";maxconn 100:单个服务器最多接受 100 个连接
    default-server inter 3s rise 2 fall 3 maxconn 100
    # default-bind [参数1] [参数n],指令为所有 frontend 或 listen 块中未显式定义 bind 的地方,统一设置绑定行为的默认参数
    # ssl:开启 SSL 支持; crt /path/to/cert.pem:指定默认证书路径; alpn h2,http/1.1:支持 HTTP/2 和 HTTP/1.1; ipv4 / ipv6:限定只绑定 IPv4 或 IPv6; transparent:用于 TPROXY 透明代理场景; defer-accept:延迟连接处理直到数据可读,提高效率。
    default-bind ssl crt /etc/ssl/private/haproxy.pem alpn h2,http/1.1

注意:

  • 忘写 mode:容易导致行为异常(默认是 TCP)
  • 忽略超时参数:会导致连接悬挂或资源被耗尽
  • 使用 HTTP 却没有 option httplog:日志中缺失请求详情
  • 不加 timeout http-request:防止慢速 HTTP 攻击时不生效
  • 不了解继承机制:容易在 frontend 或 backend 中重复配置

frontend:前端,接收客户端请求

frontend 块用于定义 接收客户端请求的入口,可以指定监听的 IP、端口、协议,并将请求转发到某个后端(backend)或做更复杂的路由处理,匹配请求(基于 URL、Host、IP、Header、方法等)。frontend = "入口",backend = "出口(服务端池)"

bash 复制代码
# http_front:是 frontend 的自定义名称
frontend http_front
    ## 监听所有 IP 上的端口/地址,如 *:80
    bind *:80
    ## 监听 443 端口,使用 SSL 证书 /etc/ssl/private/haproxy.pem
    # bind *:443 ssl crt /etc/ssl/private/haproxy.pem
    ## 指定工作模式为 HTTP,选项有 HTTP|TCP
    mode http
    ## 默认转发到后端名为 http_back 的服务器池
    default_backend http_back
    ## 访问控制规则,支持多种判断(如路径、头部、IP)
    acl is_static path_end .jpg .png .css .js
    ## 根据 ACL 条件使用不同后端
    use_backend static_back if is_static

注意:

  • 忘写 mode http:会使 HTTP 规则无法生效,表现异常
  • 多个 bind 不同端口未区分流量:建议使用 ACL 区分请求类型
  • 忽略 http-request 控制:限流、重定向、拒绝请求功能缺失
  • 日志无记录的话:确保配置了 log global 和 option httplog

backend:后端,定义服务器组和转发策略

backend 是用来定义 后端服务器池 的模块,负责处理前端 (frontend) 或中间路由转发过来的请求。你可以在 backend 中指定多个真实服务节点(server),并配置负载均衡方式、健康检查等参数。

bash 复制代码
# http_back:是 backend 的自定义名称
backend http_back
    ## 负载均衡策略,选项如下:
    # roundrobin:轮询,默认方式,平均分配请求。适用于大多数场景。
    # leastconn:优先分配给当前连接数最少的服务器。适合长连接(如数据库、API)场景。
    # source:根据客户端 IP 哈希,保持同一客户端请求固定落到一台服务器(会话保持)。
    # uri [option]:根据请求 URI 哈希,常用于静态资源缓存场景。
    # url_param <param>:根据 URL 中指定的参数值做哈希。例如 ?id=123 中的 id。
    # hdr(<name>):根据指定 HTTP 头做哈希,如:hdr(User-Agent)。
    # rdp-cookie <cookie_name>:仅用于 TCP 模式 + RDP 协议,根据 RDP cookie 实现持久会话。
    # random [draws N]:随机选择一台服务器(可选多次抽样,选最优)
    # first(仅限 backup 服务器):优先选择第一台健康的服务器
    balance roundrobin
    ## 健康检查路径
    option httpchk GET /health
    ## 健康检查响应状态码要求
    http-check expect status 200
    ## 给所有 server 设置默认参数
    # default-server [参数1] [参数n]
    ## 定义服务器,格式:<name> <IP>:<port> [check] [backup]
	# check:开启健康检查
	# backup:作为备用服务器
    # weight:权重
    # resolvers:使用 DNS 解析器,mydns:解析器的名字
    server web1 192.168.1.10:80 weight 3 check
    server web2 192.168.1.11:80 weight 1 check backup resolvers mydns
    ## 	修改请求头、添加路由规则等。
    # http-request
    # tcp-request
    ## 配合 frontend 实现会话保持(IP、cookie等)
    # stick-table
    ## 会话保持策略
    # cookie
    ## 连接超时时间
    # timeout connect
    ## 服务响应超时时间
    # timeout server

注意:

  • 会话丢失的话:使用 cookie 或 stick-table 保持 session
  • 后端负载不均:优化 balance 策略(如 leastconn)
  • 连接超时:设置合理的 timeout server 和 timeout connect
  • 后端节点不健康:检查 option httpchk 是否配置正确
  • 不支持 HTTPS 后端的话:加上 ssl verify none 让 HAProxy 与后端走 TLS

listen:同时定义 frontend 和 backend 的组合配置(简写方式)

listen 是一个组合块,将 frontend(接收请求)和 backend(转发处理)合并在一起,适合简单场景或 TCP 代理场景,比如 MySQL、Redis、FTP、SMTP 等服务的负载均衡。

bash 复制代码
# admin_stats:是 listen 的自定义名称
listen admin_stats
    # 监听端口或地址,如 *:80
    bind *:8080
    # 工作模式:http、tcp
    mode http
    ## 最大连接数
    maxconn 1000
    ## 启用日志记录(需配置 syslog)
    log global
    ## 启用的日志格式,httplog|tcplog
    option tcplog
    ## 负载均衡算法
    balance roundrobin
    ## 启用基于 Cookie 的会话保持
    cookie SRV insert indirect	
    ## 粘性表(用于限流、IP 绑定)
    stick-table
    ## 根据某字段粘性会话
    stick on src
    ## 启用状态页面
    stats enable
    ## 设置访问路径
    stats uri /haproxy?stats
    ## 设定登录提示标题	
    stats realm Haproxy\ Stats
    ## 设置访问认证
    stats auth admin:admin
    ## 刷新频率
    stats refresh 10s

注意:

  • 复杂路由逻辑:用 frontend + backend 更清晰
  • 日志无输出:添加 log global 和 option httplog
  • 会话粘性失败:检查 cookie 名称、参数一致性
  • 无监控界面:添加 stats 相关配置

peers:多节点之间的同步(如 stick-table)

peers 是 HAProxy 中用于配置多实例之间的状态同步的模块,常用于多个 HAProxy 节点之间同步 stick-table(会话表) 数据,从而实现集群中"共享状态"。如:源 IP 的请求频率(防护 DDOS、限流),用户会话保持,自定义统计(登录失败次数等)。

stick-table 是 HAProxy 用来在运行时追踪客户端状态的数据结构(例如追踪 IP 的连接数、请求数、失败数等)。这对于防止 DDoS、暴力破解、限流、会话保持非常有用。

bash 复制代码
# group_name 同步组名(多个节点使用相同组名以便互相同步)
peers <group_name>
    # <本机名> 必须与当前 HAProxy 启动时的 -L <name> 参数一致(或 global 中的 node <name>)
    peer <本机名> <本机IP>:<端口>
    peer <其他节点名> <其他IP>:<端口>

注意:

  • 所有节点都必须有相同的 peers 配置(节点名字可不同)
  • peer 名称必须唯一且不能是当前机器的名称
  • 每台机器的 bind 地址和 peer 中配置的 IP 要匹配
  • peers 同步是双向的,每台都要监听端口
  • 用于高可用部署(主-主同步),不适用于主-备场景
  • stick-table 配置中的 peers <name> 不能漏掉

resolvers:自定义 DNS 解析器

resolvers 用于配置 DNS 解析器,使 HAProxy 能动态解析和刷新服务器的 IP 地址。默认情况下,HAProxy 启动时只解析一次 DNS,如果没有配置 resolvers,域名解析不会动态更新。

这对于以下场景尤其重要:

  • 后端服务器 IP 可能变动(比如后端是 Kubernetes Pod、云主机、容器)
  • 使用主机名作为后端地址(如 server web1 app.example.com:80
bash 复制代码
# 自定义一个resolvers 名称,名称可在 server 行中引用
resolvers mydns
    # 设置 DNS 服务器
    nameserver dns1 8.8.8.8:53
    nameserver dns2 8.8.4.4:53
    # 解析重试次数
    resolve_retries 3
    # 重试超时时间
    timeout retry 1s
    # 超时时间
    timeout resolve 1s
    # 解析结果缓存多久
    hold valid 10s
    ## 对 NXDOMAIN 响应的缓存时间
    hold nx 30s
    ## 其它响应(如 SERVFAIL)的缓存时间
    hold other 30s	
    ## 拒绝响应的缓存时间
    hold refused 30s	
    ## 超时响应的缓存时间
    hold timeout 30s
    ## DNS 响应最大数据包(默认 512)
    accepted_payload_size 8192	
    ## 使用 /etc/resolv.conf 中的配置(仅 Linux)
    parse-resolv-conf 

注意:

  • 必须指定 resolvers 才能解析主机名(否则启动报错)
  • 建议设置合理的 hold valid,避免频繁解析
  • 使用多个 nameserver 做冗余,提升稳定性
  • 支持 SRV 和 A/AAAA 查询(需设置 init-addr 参数)

userlist:用户认证列表

userlist 用于定义用户名和密码列表,它相当于一个"认证数据库",本地内置用户名+密码信息,HAProxy 直接验证请求。主要用于:

  • HTTP Basic 认证(常见于管理页面、监控接口保护)
  • 配合 acl 使用,实现访问控制
  • 可用于结合 stats 页面进行访问限制
bash 复制代码
userlist <名称>
    user <用户名1> password <明文密码>
    user <用户名2> insecure-password <明文密码>
    user <用户名3> encrypted-password <加密后的密码(推荐使用 bcrypt)>

注意:

  • 不支持动态用户加载,必须在启动时写死
  • 密码推荐使用加密格式(SHA-256/512 或 bcrypt)
  • userlist 只在 HAProxy 本地生效,不能对接 LDAP 或外部认证
  • 支持多个 userlist,可按需引用

相关推荐
诚丞成20 分钟前
穿越文件之海:Linux链接与库的奇幻旅程,软硬连接与动静态库
android·linux·服务器
你才是向阳花26 分钟前
前端限流如何实现,如何防止服务器过载
运维·服务器·前端
TeleostNaCl29 分钟前
OpenWrt 搭建 samba 服务器的方法并解决 Windows 不允许访问匿名服务器的方法
运维·服务器·windows·经验分享·智能路由器
燃犀知不可乎骤得30 分钟前
qt控制台程序与qt窗口程序在读取数据库中文字段的差异!!巨坑
开发语言·数据库·qt
2301_768350231 小时前
Redis缓存-数据淘汰策略
数据库·redis·缓存
GUIQU.2 小时前
【Oracle】DCL语言
数据库·oracle
Logan Lie3 小时前
Linux运维笔记:服务器感染 netools 病毒案例
linux·运维·服务器·安全
碎梦归途5 小时前
Linux_T(Sticky Bit)粘滞位详解
linux·运维·服务器
不剪发的Tony老师6 小时前
sqlite-vec:谁说SQLite不是向量数据库?
数据库·人工智能·sqlite
DjangoJason6 小时前
计算机网络 : 应用层自定义协议与序列化
linux·服务器·计算机网络