假金方用真金镀,若是真金不镀金。
导航
- [1 工具介绍](#1 工具介绍)
- [2 配置结构](#2 配置结构)
- [3 调度算法](#3 调度算法)
- [4 应用场景](#4 应用场景)
- [4.1 七层代理 - HTTP](#4.1 七层代理 - HTTP)
- [4.2 四层代理 - TCP/UDP](#4.2 四层代理 - TCP/UDP)
- [4.3 转发规则 - ACL](#4.3 转发规则 - ACL)
- [4.4 状态管理 - Stats](#4.4 状态管理 - Stats)
- [4.5 TLS 透传与 HTTPS 终止](#4.5 TLS 透传与 HTTPS 终止)
- [5 杂七杂八](#5 杂七杂八)
1、工具介绍
HAProxy(High Availability Proxy)是一个高性能、高可用的代理与负载均衡软件。它本质上就是一个高性能的"流量调度中心",通过代理技术接收客户端请求,再利用负载均衡算法把流量分配到多台后端服务器,从而实现高并发、高可用与高扩展性。
注:Nginx 虽然也提供四/七层的负载均衡能力,但在性能和灵活度上,HAProxy 都比 Nginx 更强。
2、配置结构
HAProxy 默认的配置文件是 /etc/haproxy/haproxy.cfg,它的语法结构如下:
nginx
global
# 针对 HAProxy 程序的配置
defaults
# 默认配置(frontend/backend/listen 的公共配置区域)
frontend http-in
# 前端入口(用于接收客户端请求)
backend servers-out
# 后端服务器池(用于处理客户端请求)
listen http-in
# frontend + backend 的合体写法
注:(1)frontend 与 backend 通常都是配合出现的,不像 listen 是可以单独存在的。(2)可以放在 defaults 处的指令,也可以放在 frontend/backend/listen 处,一条指令可以在这四个地方重复出现,但在优先级上
default < frontend < backend。
3、调度算法
HAProxy 支持的调度算法非常丰富,完全可以满足各种场景中的需求,如下:
- roundrobin(轮询):按顺序一个个分配,保证任务能被均匀分配。同样也可以结合 weight 参数进行权重分配。【适合 HTTP 请求均匀场景】
- static-rr(静态轮询):和 roundrobin 类似,但不会动态调整权重影响分配。【注:后端服务器增加/减少不会立刻重新平衡,而 roundrobin 则对此比较敏感。】
- leastconn(最少连接):谁连接少,就给谁,优先选择"最闲"的服务器。【适合长连接的 TCP 请求,如 SSH、MYSQL 等】
- first(顺序优先):从上往下用,满了才换下一个,不太关心均衡。
- sticky:永远优先第一台,直到它挂掉再切换下一台。【适合日志系统的场景】
- hash(通用哈希):对某个"字段"做 hash,让同 hash 的请求尽量使用同一台服务器去处理,不频繁变动。【适合缓存命中优化】
- source(源 IP 哈希):针对源 IP 的 hash,让来自同一个客户端 IP 的请求都由同一台服务器处理。
- uri(按 URL hash):针对 URI 的 hash,让同一个 URL 的请求都由同一台服务器处理。【适合缓存命中优化】
- url_param(按 URL 参数) :针对
URI+参数的 hash,让同一个链接的请求都由同一台服务器处理。【适合用户登录优化】 - hdr(name):针对 HTTP 请求头中的某个参数进行的 hash。【适合用户登录优化】
- random:随机选服务器。
- rdp-cookie:基于远程桌面 cookie。【适合 Windows RDP 场景】
- log-hash:专门用于日志 backend。【适合日志系统的场景】
4、应用场景
以下关于 HAProxy 各种使用场景的配置示例中, global 和 defaults 的配置并非重点,我们只需把关注点集中在 frontend 和 backend 即可。
4.1、七层代理 - HTTP
nginx
global
log 127.0.0.1 local2
......
defaults
mode http
log global
......
frontend webser
bind *:80
default_backend app
backend app
balance roundrobin
server app1 192.168.1.1:80 check
server app2 192.168.1.2:80 check
4.2、四层代理 - TCP/UDP
nginx
global
log 127.0.0.1 local2
......
defaults
mode tcp
log global
......
frontend mysql
bind *:3306
default_backend mysqlservers
backend mysqlservers
balance leastconn
server dbsrv1 192.168.1.1:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300
server dbsrv2 192.168.1.2:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300
注意:TCP 模式下的
roundrobin,并不是"每个数据包轮询一次",而是"每个连接轮询一次"。
4.3、转发规则 - ACL
nginx
global
log 127.0.0.1 local2
......
defaults
mode http
log global
......
frontend webservs
bind *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html
acl url_php path_end -i .php
acl host_static hdr_beg(host) -i img. imgs. video. videos. ftp. image. download.
use_backend static if url_static or host_static
use_backend dynamic if url_php
default_backend dynamic
backend static
balance roundrobin
server node1 192.168.1.1:80 check maxconn 3000
backend dynamic
balance roundrobin
server node2 192.168.1.2:80 check maxconn 1000
4.4、状态管理 - Stats
nginx
global
log 127.0.0.1 local2
......
defaults
mode http
log global
......
listen statistics
bind *:8080 # 自定义监听端口
stats enable # 启用基于程序编译时默认设置的统计报告
stats auth admin:admin # 统计页面用户名和密码设置
stats uri /admin?stats # 自定义统计页面的 URL,默认为/haproxy?stats
stats hide-version # 隐藏统计页面上 HAProxy 的版本信息
stats refresh 30s # 统计页面自动刷新时间
stats admin if TRUE # 如果认证通过就做管理功能,可以管理后端的服务器
stats realm Hapadmin # 统计页面密码框上提示文本,默认为 Haproxy\Statistics

Stats 管理页支持的动作:
- Set state to READY:正常模式。若后端服务正常,则此操作后,后端服务将对外提供服务。
- Set state to DRAIN:排干模式,新的请求不再接收,旧的请求继续等待执行完毕。
- Set state to MAINT:维护模式。维护模式下,后端服务不再对外提供服务,并等待已有的请求结束连接,此操作会影响服务器宕机次数 Dwn(+1)、宕机时间 Dwntme。
- Health: disable checks:停止健康检查。
- Health: enable checks:启用健康检查。
- Health: force UP:强制将健康检查结果设置为 UP。指令执行后,服务器状态会马上变成 UP, 若后续健 康检查出错,服务器仍会变成 Down。
- Health: force NOLB:强制将服务剔除负载均衡。功能类似于 Health: force DOWN,区别在于 此操作不会影 响服务器宕机次数 Down、宕机时间 Dwntme。指令执行后,后端服务不 再参与负载均衡,即不对 外提供服务,若后续后端服 务恢复正常,则服务器状态会自动 转变成 UP,并继续对外提供服务。
- Health: force DOWN:强制将健康检查结果设置为 Down,此操作会影响服务器宕机次数 Dwn(+1)、宕机时间 Dwntme。指令执行后,后端服务会被强制下线,将不再对外提供服务,若后续后端服务恢复正常,则服务器状态会自动转变成 UP,并继续对外提供 服务。
- Kill Session:杀死所有会话。
4.5、TLS 透传与 HTTPS 终止
【1】HTTPS 终止:客户端向 HAProxy 发起 HTTPS 请求,HAProxy 对 HTTPS 包进行解密,然后将解密后的 HTTP 包发送到后端。在此过程中,HAProxy 是能够看到请求包中的 URL、Header、Cookie 等信息的,因此 HAProxy 能够对请求包做 ACL 的过滤转发。
nginx
global
log 127.0.0.1 local2
......
defaults
mode http
log global
......
frontend https
bind *:443 ssl crt /etc/haproxy/certs/site.pem #公私钥的合并 cat cert.pem privkey.pem > site.pem
mode http
default_backend web
backend web
mode http
server web1 127.0.0.1:8080
【2】TLS 透传:客户端向 HAProxy 发起 HTTPS 请求,HAProxy 不对 HTTPS 包进行解密,而是直接将其以 tcp 流的方式发送到后端。在此过程中,HAProxy 不能够看到请求包中的 URL、Header、Cookie 等信息的,因此 HAProxy 不能够对请求包做 ACL 的过滤转发。
nginx
global
log 127.0.0.1 local2
......
defaults
mode tcp
log global
......
frontend tls
bind *:443
mode tcp
default_backend tls_servers
backend tls_servers
mode tcp
server web1 10.0.0.1:443
5、杂七杂八
(2)常用命令
bash
#(1)配置文件语法检查
haproxy -c -V -f /etc/haproxy/haproxy.cfg
#(2)根据 sock 文件与 HAProxy 进行交互,查看各服务器状态,以及动态修改指定服务器的权重。
echo "show servers state" | socat stdio /run/haproxy/admin.sock
echo "set weight server-test 50" | socat stdio /run/haproxy/admin.sock