问题背景
在生产环境中,单台服务器的处理能力是有限的。当业务请求量增长到一定程度,一台服务器无法承载所有流量时,就必须考虑将流量分散到多台服务器上。负载均衡(Load Balancing)就是解决这一问题的核心技术。
从运维角度来看,负载均衡不仅仅是把流量分发出去那么简单。实际工作中会遇到这些问题:
某台后端服务器 CPU 飙高,其他服务器却很空闲,流量分配不均
Session 丢失问题,用户登录后被路由到另一台服务器,状态丢失
某台 RS(Real Server)宕机,但负载均衡器还在往它分流量
HTTPS 证书管理、多域名转发、路径重写等复杂路由需求
高并发场景下,负载均衡器本身成为瓶颈
本文从四种主流负载均衡方案的原理、架构、配置和适用场景出发,帮助你理解在什么情况下该选哪种方案,以及如何排查常见的负载均衡故障。
四种负载均衡方案概述
| 方案 | 工作层次 | 性能范围 | 典型场景 | 架构类型 |
|---|---|---|---|---|
| LVS | 四层(TCP/UDP) | 百万级并发 | 大流量入口、DDOS防护 | Linux 内核模块 |
| Nginx | 七层(HTTP/HTTPS) | 万级并发 | Web 服务反向代理 | 软件 |
| HAProxy | 四层/七层 | 十万级并发 | 混合场景、数据库负载 | 软件 |
| F5 | 四层/七层 | 硬件级 | 金融、电信等高端场景 | 硬件/虚拟机 |
LVS:Linux 虚拟服务器
原理概述
LVS 是 Linux 内核自带的负载均衡功能,工作在 TCP/IP 协议栈的四层。它通过 IPVS(IP Virtual Server)模块在内核态实现数据包转发,性能极高。
LVS 有三种工作模式,理解这三种模式是选型和故障排查的基础:
1. NAT 模式(Network Address Translation)
客户端请求先到达 LVS -director(调度器),LVS 修改数据包的目标 IP 和端口,将请求转发给后端 RS。RS 处理完成后返回数据,数据包再经过 LVS 修改源 IP 后返回给客户端。
Client --> LVS-Director --> RS --> LVS-Director --> Client
数据包往返都要经过 LVS,缺点是 LVS 可能成为瓶颈,优点是 RS 可以使用任意操作系统。
2. DR 模式(Direct Routing)
LVS 只修改数据包的目标 MAC 地址,将请求转发给 RS。RS 直接回复客户端,不需要经过 LVS。
Client --> LVS-Director --> RS --> Client
性能比 NAT 模式高,因为回程不走 LVS。但要求 LVS 和 RS 在同一网段,且 RS 上需要配置隐藏的 VIP。
3. TUN 模式(IP Tunneling)
类似 DR 模式,但通过 IP 隧道转发,适合跨网段场景。
架构和部署
LVS 的部署架构是 "Director + RS" 模式:
Director:负载均衡调度器,运行 LVS 内核模块,安装 ipvsadm 管理工具
RS:Real Server,实际处理请求的后端服务器
常见的高可用架构是 LVS + Keepalived:
VIP (Virtual IP) | +-------+-------+ | Keepalived | | (主备切换) | +-------+-------+ | +------+------+ | | LVS-Director LVS-Director (主节点) (备节点)
配置示例
环境说明:
LVS Director:192.168.1.10(主)、192.168.1.11(备)
VIP:192.168.1.100
RS1:192.168.1.20
RS2:192.168.1.21
目标端口:80
第一步:在 Director 上安装 ipvsadm 和 keepalived
# CentOS/RHEL yum install -y ipvsadm keepalived # Ubuntu/Debian apt-get update && apt-get install -y ipvsadm keepalived
第二步:配置 Keepalived(/etc/keepalived/keepalived.conf)
! Configuration File for keepalived
global_defs {
router_id LVS_MASTER
script_user root
enable_script_security
}
# 健康检查脚本
vrrp_script check_lvs {
script "/etc/keepalived/check_lvs.sh"
interval 3
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
nopreempt
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
check_lvs
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
# LVS 虚拟服务器配置
virtual_server 192.168.1.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 0
protocol TCP
# Real Server 1
real_server 192.168.1.20 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
# Real Server 2
real_server 192.168.1.21 80 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
第三步:配置 RS 上的隐藏 VIP(以 DR 模式为例)
在每台 RS 上执行以下脚本:
#!/bin/bash # /etc/init.d/lvs_rs_startup.sh VIP=192.168.1.100 NETMASK=255.255.255.255 DEV=lo /sbin/ip addr add $VIP/32 dev $DEV /sbin/ip route add $VIP/32 dev $DEV echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce sysctl -w net.ipv4.ip_nonlocal_bind=1
第四步:验证 LVS 配置
# 查看 LVS 规则 ipvsadm -Ln # 查看连接状态 ipvsadm -Ln --stats # 查看 Real Server 状态 ipvsadm -Ln --rate
第五步:启动服务
systemctl enable keepalived systemctl start keepalived # 手动管理 LVS(不通过 keepalived 时) ipvsadm -A -t 192.168.1.100:80 -s rr ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.20:80 -g ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.21:80 -g
常用命令
# 查看当前所有 LVS 规则 ipvsadm -Ln # 查看统计信息(连接数、流量) ipvsadm -Ln --stats # 查看速率信息 ipvsadm -Ln --rate # 清空所有规则 ipvsadm -C # 添加虚拟服务 ipvsadm -A -t 192.168.1.100:80 -s wrr # 添加 Real Server ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.20:80 -g # 删除 Real Server ipvsadm -d -t 192.168.1.100:80 -r 192.168.1.20:80 # 删除虚拟服务 ipvsadm -D -t 192.168.1.100:80 # 修改权重 ipvsadm -e -t 192.168.1.100:80 -r 192.168.1.20:80 -g -w 2 # 保存规则 ipvsadm-save > /etc/sysconfig/ipvsadm # 恢复规则 ipvsadm-restore < /etc/sysconfig/ipvsadm
调度算法
LVS 支持多种调度算法:
| 算法 | 说明 | 适用场景 |
|---|---|---|
| rr | 轮询 | 服务器性能相近 |
| wrr | 加权轮询 | 服务器性能不均 |
| lc | 最少连接 | 长连接服务 |
| wlc | 加权最少连接 | 性能不均的长连接 |
| sh | 源哈希 | Session 保持 |
| dh | 目标哈希 | 缓存场景 |
| sed | 最小延迟 | 响应时间敏感 |
| nq | 永不排队 | 高性能场景 |
优缺点分析
优点:
内核态转发,性能极高,延迟可控制在微秒级
支持四层(TCP/UDP)负载,可做数据库、消息队列负载
支持多种工作模式,适用场景广
与 Keepalived 配合实现高可用
缺点:
配置相对复杂,需要了解内核参数和 ARP 协议
NAT 模式下行流量经过 Director,可能成为瓶颈
不支持七层 URL 路由、路径重写等高级功能
健康检查功能相对简单
适用场景:
大流量入口,如 CDN 源站、DNS 入口
需要四层负载的 TCP/UDP 服务
追求极致转发性能的场景
Nginx:七层负载均衡
原理概述
Nginx 是功能丰富的 Web 服务器,同时具备强大的七层负载均衡能力。它工作在应用层,可以解析 HTTP/HTTPS 协议,根据请求 URL、Header、Cookie 等内容进行灵活路由。
Nginx 的七层负载均衡适合以下场景:
基于 URL 路径的路由(如 /api/ 走 A 服务,/web/ 走 B 服务)
基于请求头的路由(如根据 Host、User-Agent 区分)
基于 Cookie 或 Session 的会话保持
HTTPS 证书卸载(SSL Termination)
请求内容修改、访问控制
配置示例
环境说明:
Nginx LB:192.168.2.10
Web Server1:192.168.2.20:8080
Web Server2:192.168.2.21:8080
第一步:安装 Nginx
# CentOS yum install -y nginx # Ubuntu apt-get install -y nginx
第二步:配置负载均衡(/etc/nginx/nginx.conf)
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'upstream: $upstream_addr upstream_status: $upstream_status';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# 限流配置
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
# 负载均衡 upstream 配置
upstream web_cluster {
least_conn; # 最少连接调度算法
# 注意:max_fails、fail_timeout 是 Nginx Plus 商业版功能,开源版不支持
# 开源版通过第三方模块(如 ngx_http_upstream_check_module)实现主动健康检查
server 192.168.2.20:8080 weight=5;
server 192.168.2.21:8080 weight=5;
server 127.0.0.1:8080 backup; # 备份服务器
keepalive 32;
}
# IP Hash 会话保持
upstream web_cluster_ip_hash {
ip_hash;
server 192.168.2.20:8080;
server 192.168.2.21:8080;
}
# URL 路由 upstream
upstream api_backend {
server 192.168.2.30:9000;
server 192.168.2.31:9000;
}
upstream static_backend {
server 192.168.2.40:80;
server 192.168.2.41:80;
}
server {
listen 80;
server_name example.com;
client_max_body_size 100m;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_send_timeout 300s;
# 健康检查配置(开源版需要通过 separate location 实现被动检查)
# Nginx Plus 商业版支持主动健康检查:health_check interval=5 fails=3 passes=2 uri=/health.html;
# 开源版通过 max_fails、fail_timeout 在 upstream 中配置
# 默认 location - 走 web_cluster
location / {
proxy_pass http://web_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# API 路径走 api_backend
location /api/ {
proxy_pass http://api_backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 静态资源走 static_backend
location /static/ {
proxy_pass http://static_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
expires 7d;
add_header Cache-Control "public, no-transform";
}
# 健康检查页面
location /health.html {
return 200 'OK';
access_log off;
}
# 限流配置
limit_req zone=one burst=10 nodelay;
limit_conn_zone $binary_remote_addr zone=addr:10m;
}
# HTTPS 配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://web_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
}
第三步:分区级配置(针对不同 location 使用不同 upstream)
# 在 http 块中定义多个 upstream
upstream backend_a {
server 192.168.2.20:8080;
server 192.168.2.21:8080;
}
upstream backend_b {
server 192.168.2.30:8080;
server 192.168.2.31:8080;
}
# 根据用户 ID 哈希分配
upstream backend_by_uid {
hash $cookie_uid consistent;
server 192.168.2.20:8080;
server 192.168.2.21:8080;
}
第四步:常用验证命令
# 检查配置语法 nginx -t # 查看版本和编译参数 nginx -V # 热加载配置 nginx -s reload # 优雅退出 nginx -s quit # 强制退出 nginx -s stop # 查看运行状态(需要启用 stub_status) curl http://127.0.0.1/nginx_status
第五步:开启状态监控页面
在 server 块中添加:
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.0.0/16;
deny all;
}
调度算法
| 算法 | 配置 | 说明 |
|---|---|---|
| 轮询 | 默认 | 逐个分配 |
| 加权轮询 | weight=N | 权重越高分得越多 |
| 最少连接 | least_conn | 分配给连接最少的 |
| IP Hash | ip_hash | 同一 IP 固定分配到同一 RS |
| URL Hash | hash $request_uri | 同一 URL 固定分配 |
| 通用 Hash | hash $remote_addr | 自定义变量哈希 |
| 一致性 Hash | hash $remote_addr consistent | 带一致性算法的哈希 |
优缺点分析
优点:
配置简洁,学习曲线平缓
支持七层路由,功能丰富(URL 重写、请求修改、限流)
天然支持 HTTPS 证书卸载
高性能,事件驱动架构
社区活跃,生态丰富
缺点:
相比 LVS,四层转发性能略低
健康检查功能相对基础(商业版 Nginx Plus 有增强)
不支持 UDP 负载均衡(开源版)
适用场景:
Web 服务反向代理
微服务网关
前后端分离架构的路由
HTTPS 终结
HAProxy:混合负载均衡
原理概述
HAProxy 是功能最全面的负载均衡软件,同时支持四层(TCP)和七层(HTTP/HTTPS)负载均衡。相比 Nginx,HAProxy 在四层转发性能上更优,七层功能上与 Nginx 相当,配置灵活性更高。
HAProxy 的显著特点:
支持四层 TCP 负载,可用于 MySQL、Redis、RabbitMQ 等服务
支持七层 HTTP/HTTPS 负载,功能与 Nginx 类似
支持 ACL 条件路由,配置极其灵活
支持多种健康检查方式
支持会话保持(Cookie 插入、Cookie 感知)
支持请求限流、连接限制
支持统计页面
支持代理协议(Proxy Protocol)
配置示例
环境说明:
HAProxy LB:192.168.3.10
MySQL Server1:192.168.3.30:3306
MySQL Server2:192.168.3.31:3306
Web Server1:192.168.3.20:8080
Web Server2:192.168.3.21:8080
第一步:安装 HAProxy
# CentOS/RHEL yum install -y haproxy # Ubuntu/Debian apt-get install -y haproxy
第二步:配置 HAProxy(/etc/haproxy/haproxy.cfg)
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /var/run/haproxy-admin.sock mode 660 level admin stats timeout 30s user haproxy group haproxy daemon maxconn 40960 nbthread 4 tune.bufsize 16384 tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout connect 10s timeout client 30s timeout server 30s timeout http-request 10s timeout http-keep-alive 10s #--------------------------------------------------------------------- # 统计页面配置 #--------------------------------------------------------------------- listen stats bind :8404 stats enable stats uri /stats stats refresh 30s stats realm Haproxy Statistics stats auth admin:password123 #--------------------------------------------------------------------- # 七层 HTTP 负载均衡(Web 服务) #--------------------------------------------------------------------- frontend http_front bind :80 mode http default_backend web_backend # 根据 URL 路径路由 acl url_api path_beg /api/ acl url_admin path_beg /admin/ use_backend api_backend if url_api use_backend admin_backend if url_admin backend web_backend mode http balance roundrobin option httpchk GET /health HTTP/1.0 http-check expect status 200 server web1 192.168.3.20:8080 check inter 2000 rise 2 fall 3 weight 100 server web2 192.168.3.21:8080 check inter 2000 rise 2 fall 3 weight 100 backend api_backend mode http balance leastconn option httpchk GET /api/health cookie SERVERID insert indirect nocache server api1 192.168.3.30:8080 check inter 2000 rise 2 fall 3 weight 100 cookie api1 server api2 192.168.3.31:8080 check inter 2000 rise 2 fall 3 weight 100 cookie api2 backend admin_backend mode http balance source option httpchk GET /admin/health server admin1 192.168.3.40:8080 check inter 2000 rise 2 fall 3 #--------------------------------------------------------------------- # 四层 TCP 负载均衡(MySQL) #--------------------------------------------------------------------- frontend mysql_front bind :3306 mode tcp default_backend mysql_backend backend mysql_backend mode tcp balance roundrobin option mysql-check user haproxy_check server mysql1 192.168.3.30:3306 check port 3306 inter 2000 rise 2 fall 3 weight 100 server mysql2 192.168.3.31:3306 check port 3306 inter 2000 rise 2 fall 3 weight 100 backup #--------------------------------------------------------------------- # 四层 TCP 负载均衡(Redis) #--------------------------------------------------------------------- frontend redis_front bind :6379 mode tcp default_backend redis_backend backend redis_backend mode tcp balance leastconn option redis-check server redis1 192.168.3.50:6379 check inter 2000 rise 2 fall 3 server redis2 192.168.3.51:6379 check inter 2000 rise 2 fall 3 #--------------------------------------------------------------------- # HTTPS 终结 + 七层负载 #--------------------------------------------------------------------- frontend https_front bind :443 ssl crt /etc/haproxy/certs/example.com.pem mode http default_backend web_backend # 根据 Host 头路由 acl host_api hdr(host) -i api.example.com acl host_static hdr(host) -i static.example.com use_backend api_backend if host_api use_backend static_backend if host_static
第三步:HAProxy 四层 + 七层混合配置示例
# 四层代理 MySQL 读写分离场景 listen mysql_rw_split bind 0.0.0.0:3306 mode tcp balance roundrobin # 写操作发往主库 acl is_write sql_is_write sql_is_write payload(0,0,SHOW VARIABLES LIKE 'sql_mode') use-server master if is_write server master 192.168.3.30:3306 check inter 1s rise 2 fall 2 server slave1 192.168.3.31:3306 check inter 1s rise 2 fall 2 server slave2 192.168.3.32:3306 check inter 1s rise 2 fall 2
第四步:常用命令
# 验证配置 haproxy -c -f /etc/haproxy/haproxy.cfg # 启动服务 systemctl enable haproxy systemctl start haproxy # 重载配置(不停机) systemctl reload haproxy # 查看状态 systemctl status haproxy # 查看前端/后端统计 echo "show stat" | socat stdio /var/run/haproxy-admin.sock echo "show info" | socat stdio /var/run/haproxy-admin.sock echo "show backend" | socat stdio /var/run/haproxy-admin.sock # 查看所有服务器状态 echo "show servers state" | socat stdio /var/run/haproxy-admin.sock
第五步:MySQL 健康检查用户创建
-- 在 MySQL 中创建 HAProxy 专用健康检查用户 CREATE USER 'haproxy_check'@'%' IDENTIFIED BY 'check_password'; GRANT SELECT ON *.* TO 'haproxy_check'@'%'; FLUSH PRIVILEGES;
ACL 条件路由示例
# 基于 URL 路径 acl url_static path_beg /static /images /css /js acl url_api path_beg /api/v1 /api/v2 # 基于请求头 acl is_mobile req.hdr(User-Agent) -i mobile android iphone acl is_internal src 192.168.0.0/16 10.0.0.0/8 # 基于 Cookie acl has_session cookie(SESSIONID) -m found # 组合条件 acl needs_cache url_static -i || url_api -i # 基于请求方法 acl is_upload method POST acl is_delete method DELETE # 根据条件选择后端 use_backend cache_backend if needs_cache use_backend api_backend if url_api
调度算法
| 算法 | 配置 | 说明 |
|---|---|---|
| 轮询 | balance roundrobin | 默认,轮询分配 |
| 权重轮询 | balance roundrobin | server 配置 weight |
| 最少连接 | balance leastconn | 连接数最少优先 |
| 权重最少连接 | balance leastconn | 结合 weight |
| 源IP哈希 | balance source | 同一 IP 固定 RS |
| URI 哈希 | balance uri | 同一 URI 固定 RS |
| URL 参数哈希 | balance url_param | 根据 URL 参数哈希 |
| 随机 | balance random | 随机选择 |
| 一致性哈希 | hash-type consistent | 一致性哈希算法 |
优缺点分析
优点:
四层/七层同时支持,场景覆盖最全
配置极其灵活,ACL 功能强大
健康检查方式丰富(TCP/HTTP/SQL/MYSQL/Redis)
会话保持方式多样(Cookie 插入/感知/源 IP)
统计页面功能完善
性能优秀,延迟低
缺点:
配置相对复杂,学习成本较高
不支持热更新(重载会短暂断连)
官方文档不够友好
适用场景:
数据库负载均衡(MySQL/PostgreSQL/Redis)
混合四层/七层负载需求
需要灵活路由规则的场景
微服务架构的入口网关
F5:硬件负载均衡
概述
F5 BIG-IP 是企业级硬件负载均衡设备,提供四层和七层负载均衡功能。相比软件方案,F5 提供硬件级别的性能和稳定性,以及厂商级的技术支持。
F5 与软件方案的对比
| 维度 | F5 | 软件方案 |
|---|---|---|
| 性能 | 硬件芯片,几十 Gbps | 受限于服务器性能 |
| 可靠性 | 电信级,99.999% | 依赖软件实现 |
| 功能 | 完整 ADC 功能 | 基础负载功能 |
| 成本 | 数十万起 | 开源免费 |
| 维护 | 厂商支持 | 自行维护 |
| 灵活性 | 有限 | 高 |
F5 常用概念
Virtual Server(虚拟服务器):对外提供服务的 IP + 端口
Pool(服务器池):后端 RS 的逻辑分组
Pool Member(池成员):具体的 RS IP + 端口
Node(节点):后端服务器的 IP
Health Monitor(健康检查):检测 RS 可用性的机制
iRule:基于 TCL 的流量编程,可自定义复杂逻辑
Profile:处理特定协议(如 HTTP、SSL)的配置集合
基础配置流程(Big-IP LTM)
第一步:创建节点
# TMSH 命令行
create ltm node 192.168.10.20 { address 192.168.10.20 }
create ltm node 192.168.10.21 { address 192.168.10.21 }
第二步:创建健康检查
# HTTP 健康检查
create ltm monitor http http_monitor {
defaults-from http
send "GET /health HTTP/1.0
"
recv "200"
}
# TCP 健康检查
create ltm monitor tcp tcp_monitor {
defaults-from tcp
interval 5
timeout 16
}
# HTTPS 健康检查
create ltm monitor https https_monitor {
defaults-from https
send "GET /health HTTP/1.0
"
recv "200"
}
第三步:创建服务器池
create ltm pool web_pool {
members:
192.168.10.20:80 {
monitor http_monitor
session monitor
}
192.168.10.21:80 {
monitor http_monitor
session monitor
}
load-balancing-mode round-robin
monitor min 1 of http_monitor
}
第四步:创建虚拟服务器
create ltm virtual web_vs {
destination 192.168.1.100:80
ip-protocol tcp
pool web_pool
profiles {
http { }
tcp { }
}
vlans disabled
}
第五步:配置 SSL 终结
# 创建客户端 SSL 证书
create ltm auth cert my cert {
cert-key-chain {
default {
cert /config/ssl.crt/server.crt
key /config/ssl.key/server.key
}
}
}
# 创建 SSL Profile
create ltm profile client-ssl ssl_clientssl {
cert /config/ssl.crt/server.crt
key /config/ssl.key/server.key
}
# 应用到虚拟服务器
modify ltm virtual web_vs profiles add {
ssl_clientssl { context clientside }
}
第六步:常用 TMSH 命令
# 查看虚拟服务器状态
show ltm virtual
# 查看池成员状态
show ltm pool web_pool members
# 查看节点状态
show ltm node
# 查看统计
show ltm virtual web_vs stats
show ltm pool web_pool stats
# 禁用/启用池成员
modify ltm pool web_pool members modify { 192.168.10.20:80 { session disabled } }
modify ltm pool web_pool members modify { 192.168.10.20:80 { session enabled } }
# 保存配置
save sys config
适用场景
金融、证券、电信等对稳定性要求极高的行业
大流量入口,需要硬件级性能
需要复杂流量管理(如策略路由、流量镜像)
需要专业厂商支持和 SLA 保障
四种方案横向对比
性能对比
| 指标 | LVS | Nginx | HAProxy | F5 |
|---|---|---|---|---|
| 四层转发性能 | 极高(微秒级) | 中等 | 高 | 极高(硬件加速) |
| 七层转发性能 | 不支持 | 高 | 高 | 高 |
| 并发连接 | 百万级 | 万级 | 十万级 | 百万级 |
| 内存占用 | 极低 | 低 | 中等 | - |
功能对比
| 功能 | LVS | Nginx | HAProxy | F5 |
|---|---|---|---|---|
| 四层负载 | 支持 | 不支持 | 支持 | 支持 |
| 七层负载 | 不支持 | 支持 | 支持 | 支持 |
| 健康检查 | 基础 | 基础 | 丰富 | 丰富 |
| 会话保持 | 支持 | 支持 | 支持 | 支持 |
| URL 路由 | 不支持 | 支持 | 支持 | 支持 |
| SSL 终结 | 不支持 | 支持 | 支持 | 支持 |
| ACL 规则 | 不支持 | 支持 | 支持 | 支持(iRule) |
| 高可用 | Keepalived | Keepalived | 自带 | 集群模式 |
| 配置复杂度 | 高 | 低 | 高 | 中 |
成本对比
| 方案 | License 成本 | 硬件成本 | 维护成本 |
|---|---|---|---|
| LVS | 开源免费 | 低 | 中 |
| Nginx | 开源免费/商业版 | 低 | 中 |
| HAProxy | 开源免费 | 低 | 中 |
| F5 | 数十万起 | 数十万起 | 低(厂商支持) |
选型决策树
业务场景 │ ├─── 大流量入口(如 CDN 源站、DNS) │ │ │ └─── LVS + Keepalived │ ├─── Web 服务反向代理、七层路由 │ │ │ ├─── 场景简单、功能要求不高 │ │ └─── Nginx │ │ │ └─── 场景复杂、需要 ACL 灵活路由 │ └─── HAProxy │ ├─── 数据库、缓存等四层负载 │ │ │ └─── HAProxy │ ├─── 金融、电信等高端场景 │ │ │ └─── F5 │ └─── 混合场景(既需要四层又需要七层) │ └─── HAProxy
实战:负载均衡常见故障排查
故障一:LVS 后端服务器全 Down
现象:
ipvsadm -Ln # 所有 RS 都是 0 activeConn # VIP 无法访问
排查步骤:
检查 LVS 进程是否正常
systemctl status keepalived ipvsadm -Ln --stats
检查 VRRP 协议是否正常
# 在备节点查看日志 tail -f /var/log/messages | grep -i keepalived tcpdump -i eth0 vrrp -nn
检查 VIP 是否正常绑定
ip addr show eth0 # 应该看到 192.168.1.100
检查 RS 健康状态
# 在 LVS Director 本地测试 RS 连通性 curl -v http://192.168.1.20/health telnet 192.168.1.20 80
检查 RS 的 ARP 设置(DR 模式)
# 在 RS 上检查 cat /proc/sys/net/ipv4/conf/lo/arp_ignore cat /proc/sys/net/ipv4/conf/lo/arp_announce # 应该分别是 1 和 2
修复方案:
确认 RS 服务恢复
systemctl start httpd # 或其他对应服务
如果是 ARP 问题,修复 RS 配置
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce # 永久生效需要写入 sysctl.conf
如果是 Keepalived 问题,检查配置后重载
systemctl reload keepalived
故障二:Nginx 502 Bad Gateway
现象:
curl -v http://example.com # HTTP/1.1 502 Bad Gateway
排查步骤:
检查 Nginx 错误日志
tail -50 /var/log/nginx/error.log
检查 upstream 配置
nginx -t
检查后端服务是否正常
curl -v http://192.168.2.20:8080/health curl -v http://192.168.2.21:8080/health
检查后端服务进程和端口
netstat -tlnp | grep 8080 ps aux | grep java
检查后端服务资源
top -Hp $(pgrep -f java) free -h df -h
检查连接数
# Nginx 连接状态 curl http://127.0.0.1/nginx_status # 系统连接数 netstat -anp | grep :8080 | wc -l ss -s
修复方案:
如果是后端服务挂了,重启服务
systemctl restart java-app # 或对应服务
如果是连接数满,优化配置
# 增加 worker_connections # 增加 worker_rlimit_nofile # 添加更多 upstream 成员
如果是后端超时,调整超时时间
proxy_connect_timeout 60s; proxy_read_timeout 120s;
故障三:HAProxy 后端 session 不均衡
现象:
# 查看统计 echo "show stat" | socat stdio /var/run/haproxy-admin.sock | grep web_backend # 发现 session 数相差巨大
排查步骤:
检查负载算法配置
grep "balance" /etc/haproxy/haproxy.cfg
检查 RS 权重是否合理
# 当前配置 grep "weight" /etc/haproxy/haproxy.cfg # 实际生效的权重 echo "show backend" | socat stdio /var/run/haproxy-admin.sock
检查是否有 RS 频繁故障
# 查看详细状态 echo "show servers state" | socat stdio /var/run/haproxy-admin.sock
检查是否存在单点故障
# 查看哪些 server 处于 UP 状态 echo "show stat" | socat stdio /var/run/haproxy-admin.sock | grep web_backend | grep -v BACKUP
修复方案:
调整权重使负载均衡
# 修改配置文件 server web1 192.168.3.20:8080 weight 100 server web2 192.168.3.21:8080 weight 80 # 重载 systemctl reload haproxy
如果是 leastconn 算法但 RS 性能不均,切换算法
# 改为 roundrobin balance roundrobin
启用会话保持
# 源 IP 会话保持 balance source # 或 Cookie 会话保持 cookie SERVERID insert indirect nocache server web1 192.168.3.20:8080 cookie w1 weight 100 server web2 192.168.3.21:8080 cookie w2 weight 100
故障四:F5 虚拟服务器无法访问
排查步骤:
检查虚拟服务器状态
show ltm virtual web_vs
检查池成员状态
show ltm pool web_pool members
检查节点状态
show ltm node
检查 VLAN 和自 IP
show net vlan show net self
检查路由
show route
检查 SSL 证书
list ltm profile client-ssl ssl_clientssl
修复方案:
如果池成员 DOWN,重启服务或修复网络
# 临时禁用故障成员
modify ltm pool web_pool members modify { 192.168.10.20:80 { session disabled } }
# 修复后重新启用
modify ltm pool web_pool members modify { 192.168.10.20:80 { session enabled } }
如果是证书问题,重新上传证书
# 上传证书
upload /tmp/server.crt
upload /tmp/server.key
# 重新创建 profile
create ltm profile client-ssl ssl_clientssl {
cert /config/ssl.crt/server.crt
key /config/ssl.key/server.key
}
生产环境风险提醒
LVS 风险点
DR 模式 ARP 问题:RS 的 arp_ignore 和 arp_announce 必须正确配置,否则会响应当前网络 ARP,导致流量无法经过 LVS
NAT 模式性能瓶颈:双向流量都经过 LVS,高流量场景下 LVS 本身可能成为瓶颈
Keepalived 脑裂:网络分区可能导致主备同时认为对方故障,各自抢占 VIP
iptables 规则冲突:如果服务器上有 iptables 规则,可能与 LVS 冲突
Nginx 风险点
worker_connections 限制:默认值可能不够,需要根据预估并发调整
** upstream keepalive 配置**:可以减少连接建立开销,但过大可能占用过多内存
proxy_set_header 丢失:如果未正确设置 X-Forwarded-For,后端无法获取真实客户端 IP
502 后端全挂:所有 upstream 都不可用时返回 502,需要配置 backup server
HAProxy 风险点
重载连接中断:使用 systemctl reload haproxy 时,已建立的连接会中断
maxconn 限制:如果 frontend 和 backend 的 maxconn 设置不当,可能导致排队或拒绝
健康检查过于频繁:频繁的健康检查可能影响后端性能,也可能误判
四层代理端口冲突:如果后端服务也在监听相同端口,需要注意地址复用
F5 风险点
配置未保存:使用 TMSH 修改配置后未执行 save sys config,重启会丢失
License 过期:F5 设备 License 过期后会降级为 10Mbps 限速模式
iRule 性能:复杂的 iRule 可能在高频流量下影响性能
升级风险:固件升级有风险,升级前需要备份配置并在测试环境验证
总结
四种负载均衡方案各有适用场景:
LVS 适合作为大流量入口的四层负载均衡,配合 Keepalived 实现高可用。它的性能最优,但功能相对基础,不适合需要复杂七层路由的场景。
Nginx 适合 Web 服务的七层反向代理,配置简洁,是中小规模 Web 架构的首选。它的七层功能足够应对大部分场景,但四层转发是短板。
HAProxy 是功能最全面的软件负载均衡方案,同时支持四层和七层,配置灵活,健康检查丰富。如果你的架构需要同时处理 Web 流量和数据库流量,HAProxy 是首选。
F5 适合金融、电信等对稳定性和性能有极高要求的高端场景,但成本高昂。普通业务不建议使用。
实际生产环境中,常见的组合方式:
LVS 作为入口层四层负载 + Nginx/HAProxy 作为七层网关:兼顾性能和功能
HAProxy 作为统一入口:同时处理四层和七层流量
DNS 轮询 + LVS:实现简单的负载均衡和高可用
选择负载均衡方案时,需要综合考虑流量规模、功能需求、运维成本和技术储备等因素。对于大部分互联网业务,建议从 Nginx 或 HAProxy 起步,根据实际需求逐步演进。
全部0条评论
快来发表一下你的评论吧 !