Appearance
负载均衡基础
负载均衡用于把客户端请求分发到多台后端,日常关注点在四层和七层区别、调度算法、健康检查、会话保持、故障摘除和入口高可用。
一、先分清两个问题
负载均衡和高可用经常一起出现,但它们不是一回事。
| 问题 | 关注点 | 常见方案 |
|---|---|---|
| 负载均衡 | 请求怎么分到多台后端 | LVS、HAProxy、Nginx、云负载均衡 |
| 高可用 | 当前入口坏了以后谁接管 | Keepalived、云厂商 VIP、DNS、集群控制面 |
一个简单链路:
带高可用入口:
我个人会把这两个问题分开设计:先确认流量如何分发,再确认入口故障时怎么切换。只搭一个负载均衡实例,后端再多也挡不住入口单点。
二、四层和七层
四层负载均衡工作在 TCP/UDP 连接层。它主要看 IP、端口和连接信息,不理解 HTTP URI、Header、Cookie。
七层负载均衡工作在应用层。HTTP 场景下,它可以看域名、路径、Header、Cookie、状态码和响应时间。
| 类型 | 看什么 | 常见能力 | 常见工具 |
|---|---|---|---|
| 四层 | IP、端口、TCP/UDP 连接 | 转发、连接调度、吞吐高 | LVS、云四层 LB |
| 七层 | HTTP 请求内容 | 域名路由、路径路由、Header、Cookie、TLS | HAProxy、Nginx、云七层 LB |
例子:
| 需求 | 更适合 |
|---|---|
| MySQL 3306 TCP 转发 | 四层 |
| Redis 6379 TCP 转发 | 四层 |
api.example.com 转发到 API 集群 | 七层 |
/admin/ 和 /api/ 走不同后端 | 七层 |
| 按 Cookie 做会话保持 | 七层 |
四层不是“低级”,七层也不是天然更好。四层路径短、性能好、协议透明;七层可观察性和规则能力更强,但也更容易把入口规则写复杂。
三、常见架构
单入口负载均衡:
双入口高可用:
多层入口:
多层入口不是越多越稳。每多一层,就多一份超时、日志、真实 IP、健康检查和故障定位成本。小环境里两层已经够用:一层 VIP/云 LB,一层七层代理。
四、调度算法
常见算法:
| 算法 | 含义 | 适用情况 |
|---|---|---|
| 轮询 | 请求依次分给后端 | 后端规格接近,请求耗时接近 |
| 加权轮询 | 权重大分到更多请求 | 后端机器规格不同 |
| 最少连接 | 分给当前连接少的后端 | 请求耗时差异大 |
| 源地址哈希 | 同一来源尽量打到同一后端 | 简单会话保持 |
| URI 哈希 | 同一 URI 尽量打到同一后端 | 缓存类服务 |
调度算法只能决定“怎么分”,不能修好后端本身。后端接口慢、数据库慢、GC 卡顿时,换算法通常只是让故障表现变得不一样。
五、健康检查
健康检查用于判断后端是否还能接流量。常见检查方式:
| 类型 | 检查内容 | 优缺点 |
|---|---|---|
| TCP 检查 | 端口能否连接 | 简单,但只能说明端口开着 |
| HTTP 检查 | 请求健康接口 | 更接近业务,但接口要写得轻 |
| 脚本检查 | 自定义逻辑 | 灵活,维护成本高 |
HTTP 健康检查常见路径:
text
/health
/ready
/actuator/health健康检查接口要轻,通常只检查进程是否可服务、关键依赖是否可用。把复杂数据库查询塞进健康检查,会让入口层自己制造压力。
六、会话保持
会话保持是让同一个用户尽量访问同一台后端。常见方式:
| 方式 | 说明 | 风险 |
|---|---|---|
| 源 IP 哈希 | 同一来源 IP 固定到后端 | NAT 场景下很多用户是同一 IP |
| Cookie | 入口写入或读取 Cookie | 只适合 HTTP |
| 后端共享 session | session 放 Redis/数据库 | 应用要支持 |
| 无状态 token | 登录态不依赖单台后端 | 应用改造更多 |
源 IP 哈希很方便,但办公室出口、运营商 NAT、移动网络都会让 IP 分布变形。核心业务多实例部署时,我更倾向把 session 外置或做无状态登录,少依赖入口层粘住某台机器。
七、真实 IP
七层代理后,后端看到的来源 IP 可能是代理地址。HTTP 场景通常靠请求头传递:
nginx
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;HAProxy 常见:
haproxy
option forwardfor # 在 X-Forwarded-For 里追加客户端 IP多层代理时,真实 IP 要配可信代理范围。应用直接相信客户端传来的 X-Forwarded-For,日志和限流都会被伪造。
八、常见方案对比
| 方案 | 层次 | 特点 | 常见场景 |
|---|---|---|---|
| LVS | 四层 | 内核 IPVS,性能高,配置偏网络 | TCP 高吞吐入口 |
| HAProxy | 四层/七层 | 健康检查、ACL、统计清楚 | API、Web、TCP 代理 |
| Nginx | 七层为主 | 静态资源、反向代理、TLS 常用 | Web 入口、静态站点 |
| Keepalived | 高可用 | VRRP、VIP 漂移 | 给 LVS/HAProxy/Nginx 做入口 HA |
| 云负载均衡 | 四层/七层 | 托管,少维护机器 | 云上生产入口 |
九、排查入口
负载均衡故障常见分层:
| 层 | 检查项 |
|---|---|
| 客户端到入口 | DNS、VIP、端口、防火墙 |
| 入口自身 | 进程、监听、配置、日志 |
| 健康检查 | 后端是否被摘除 |
| 入口到后端 | 路由、防火墙、后端端口 |
| 后端应用 | 状态码、响应时间、应用日志 |
常用命令:
bash
ss -lntp # 看入口监听端口
curl -I http://vip/ # 从入口访问
curl -I http://backend/ # 绕过入口访问后端
tcpdump -nn host 10.0.0.10 and port 80 # 看流量是否到达指定主机我排查这类问题时会先做两次访问:访问 VIP,再直接访问后端。VIP 不通但后端通,入口层优先;后端也不通,就回到应用、端口和网络。