侧边栏壁纸
  • 累计撰写 157 篇文章
  • 累计创建 21 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

多台服务器前,流量该怎么分?四层和七层,负载均衡差在哪?

YaFuX
2026-05-29 / 0 评论 / 0 点赞 / 2 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

假设 Java 服务最初只有一台机器:

客户端
    ↓
203.0.113.10:8080
    ↓
Java 服务

随着访问量增加,单机开始出现:

CPU 使用率过高
连接数量增长
请求排队
GC 压力增加
响应延迟上升

于是我们增加了三台服务器:

Server A
Server B
Server C

但新的问题马上出现:

客户端应该连接哪一台?

DNS 轮询就够了吗?

一条 TCP 连接应该固定到一台后端吗?

能不能根据 URL 把请求发给不同服务?

四层负载均衡能不能看到 HTTP Header?

七层负载均衡为什么能按路径转发?

四层负载均衡一定不建立 TCP 连接吗?

七层代理一定比四层慢吗?

HTTPS 流量不解密,还能做七层路由吗?

Nginx、LVS、网关分别工作在哪一层?

负载均衡器宕机后,多台后端还有意义吗?

原资料用“高并发”引出四层和七层负载均衡,并将四层与 TCP、UDP 联系起来,将七层与 HTTP 联系起来。

但真正理解它们,不能只背:

四层看 IP 和端口
七层看 URL

更重要的是理解:

在哪个粒度做选择?
能读取哪些信息?
客户端连接终止在哪里?
后端故障时怎样切换?

一、负载均衡解决什么?

增加服务器以后,系统从:

一个入口
    ↓
一台服务器

变成:

一个入口
    ↓
多台服务器

负载均衡器负责把流量分配出去:

客户端
    ↓
负载均衡器
    ├── Server A
    ├── Server B
    └── Server C

它主要解决:

流量分配
资源利用
水平扩容
故障隔离
入口统一

Nginx 官方也把负载均衡的目标描述为优化资源利用、提升吞吐、降低延迟,并支持容错配置。

但要注意:

负载均衡不等于高可用。

如果只有一台负载均衡器:

所有客户端
    ↓
唯一负载均衡器
    ↓
后端集群

那么它本身仍可能成为单点。

高可用还需要考虑:

负载均衡器冗余
地址漂移
故障检测
配置同步
状态恢复
跨可用区部署

二、四层看什么?

四层负载均衡主要工作在传输层信息附近。

典型决策信息包括:

协议
源 IP
源端口
目标 IP
目标端口
连接状态

例如客户端访问:

203.0.113.100:443

四层负载均衡器可以把新连接选择到:

10.0.0.10:443
10.0.0.11:443
10.0.0.12:443

Linux IPVS 就是在内核中实现传输层负载均衡,按连接粒度将 TCP 或 UDP 服务分配给真实服务器。

选择粒度

典型四层模型是:

新连接到来
    ↓
选择一台后端
    ↓
该连接后续数据继续发送到同一后端

也就是说,调度对象通常是:

连接

而不是某条 HTTP 请求。

如果同一条 TCP 连接承载 100 次 HTTP 请求,四层设备通常仍把这 100 次请求交给同一台后端,因为它们属于同一条传输层连接。


三、四层不懂 URL

HTTP 请求:

GET /api/orders HTTP/1.1
Host: shop.example.com
Cookie: session=abc

典型四层调度不需要解析:

/api/orders
shop.example.com
session=abc

所以它不能直接基于 HTTP 语义执行:

/api/users
    → 用户服务

/api/orders
    → 订单服务

它更适合:

443 端口
    → 一组 HTTPS 服务器

3306 端口
    → 一组数据库代理

6379 端口
    → 一组 Redis 服务

Nginx 的 Stream 模块就是面向 TCP、UDP 和 Unix Domain Socket 数据流的代理模块。

示例:

stream {
    upstream rpc_backend {
        server 10.0.0.10:9000;
        server 10.0.0.11:9000;
        server 10.0.0.12:9000;
    }

    server {
        listen 9000;
        proxy_pass rpc_backend;
    }
}

这里代理的是 TCP 数据流,不要求理解其中承载的是:

RPC
数据库协议
自定义二进制协议

四、四层不只一种实现

“四层”描述的是调度所依赖的信息层次,不代表所有实现方式都相同。

常见实现可以分成两类。

1. 数据包转发

例如 IPVS,可以通过不同转发方式把连接发送到真实服务器。

IPVS 项目提供的典型模式包括:

NAT
Direct Routing
IP Tunneling

并在内核中按连接粒度调度。

NAT

请求进入负载均衡器后:

VIP
    ↓
改写目标地址
    ↓
真实服务器

响应通常也需要经过负载均衡器,以便恢复对外地址。LVS/NAT 的核心正是改写请求目标地址,并在响应方向改写源地址,使客户端只看到虚拟服务地址。

Direct Routing

负载均衡器选择后端后,通过链路层等方式把请求交给真实服务器。

响应可以由真实服务器直接返回客户端,从而减少返回流量经过负载均衡器的压力。

Tunneling

负载均衡器把原始数据包封装进隧道,发送给可能位于不同网络的真实服务器。

真实服务器解封装后处理请求,并可以直接返回客户端。

2. TCP 代理

Nginx Stream 等实现可以接受客户端 TCP 连接,再建立到后端的 TCP 连接:

客户端 TCP 连接
    ↓
四层代理
    ↓
后端 TCP 连接

因此不能简单记成:

四层负载均衡永远不终止 TCP

正确说法是:

四层负载均衡主要依据传输层信息做决策,但具体实现可能是数据包转发,也可能是 TCP 代理。


五、七层看什么?

七层负载均衡理解应用层协议。

以 HTTP 为例,它可以读取:

Host
Path
Method
Header
Cookie
Query
部分 Body

于是可以执行:

Host: api.example.com
    → API 集群

Host: static.example.com
    → 静态资源集群

或者:

/api/users
    → 用户服务

/api/orders
    → 订单服务

/api/payments
    → 支付服务

Nginx 的 HTTP 模块可以根据请求的 Server Name 和 Location 规则处理请求,并通过 proxy_pass 将请求代理到上游服务器。

示例:

http {
    upstream user_service {
        server 10.0.0.10:8080;
        server 10.0.0.11:8080;
    }

    upstream order_service {
        server 10.0.0.20:8080;
        server 10.0.0.21:8080;
    }

    server {
        listen 80;

        location /api/users/ {
            proxy_pass http://user_service;
        }

        location /api/orders/ {
            proxy_pass http://order_service;
        }
    }
}

六、七层按请求分配

七层代理能够识别 HTTP 请求边界,因此它的选择粒度可以是:

请求

而不只是:

连接

例如客户端与 Nginx 保持一条持久连接:

客户端 TCP 连接
    ↓
Nginx

客户端连续发送:

GET /users/1
GET /orders/9
GET /users/2

七层代理可以分别处理这些请求,甚至将后续请求分配给不同上游。

Nginx 官方说明,在轮询或最少连接等 HTTP 负载均衡方式下,同一客户端后续请求可能被分配到不同服务器,并不保证永久落在同一后端。

这就是典型区别:

四层
    一条连接通常固定后端

七层
    可以按每个应用请求重新选择

七、七层通常是反向代理

典型 HTTP 七层负载均衡器会形成两段连接:

客户端
    ↓
客户端到代理的连接
    ↓
七层代理
    ↓
代理到后端的连接
    ↓
后端服务器

它需要先接收并解析客户端 HTTP 请求,随后再向后端发起或复用上游连接。

所以在典型反向代理模型中:

客户端连接
≠
后端连接

七层代理可以修改:

HTTP Header
请求路径
Host
缓存策略
压缩策略
认证信息

这也是它能实现:

鉴权
限流
缓存
灰度发布
重写
WAF

等能力的基础。


八、HTTPS 怎么看路径?

HTTPS 中,HTTP 内容被 TLS 加密。

如果负载均衡器只做 TCP 转发:

客户端
    ↓
加密 TLS 数据
    ↓
四层负载均衡
    ↓
后端服务器解密

负载均衡器通常不能看到明文:

URL
HTTP Header
Cookie
Body

这种方式常称为:

TLS Passthrough

如果需要按 HTTP Path 转发,通常需要在代理处终止 TLS:

客户端
    ↓
TLS
    ↓
七层代理解密
    ↓
读取 HTTP
    ↓
选择后端

然后代理与后端之间可以:

使用明文 HTTP

或者再次建立:

新的 TLS 连接

Nginx Stream 也可以通过预读初始 TLS 信息分析 SNI,而无需完整代理 HTTP;这说明“层数”在真实产品中可能存在有限的跨层观察,但它仍不等于解析完整的 HTTP 请求。


九、算法怎么选?

常见负载均衡算法包括:

轮询

请求 1 → A
请求 2 → B
请求 3 → C
请求 4 → A

适合后端能力相近、请求成本接近的场景。

加权轮询

A 权重 5
B 权重 3
C 权重 2

适合机器配置不同或希望逐步放量。

最少连接

选择当前活跃连接较少的后端。

Nginx 的 HTTP 和 Stream Upstream 都支持最少连接等调度方式。

哈希

根据某个 Key 选择后端:

客户端 IP
用户 ID
Cookie
URL 参数

适合需要一定稳定映射的场景。

但哈希不等于可靠会话管理。

节点增加、删除或异常时,映射仍可能变化。


十、连接数不等于负载

假设:

Server A
    1000 条空闲连接

Server B
    100 条高频请求连接

按连接数看:

A 更忙

但按真实 CPU 和请求量看:

B 可能更忙

因此负载指标可能包括:

活跃连接数
请求数
响应时间
CPU 使用率
队列长度
错误率
自定义权重

不过指标越复杂,采集和调度成本也越高。

负载均衡策略必须服务于真实瓶颈,而不是单纯追求算法复杂。


十一、健康检查是什么?

负载均衡器不能把新流量继续发给已经故障的服务器。

因此需要健康判断:

Server A:健康
Server B:异常
Server C:健康

被动检查

真实请求访问失败后,暂时降低或停止向该节点分配流量。

Nginx 开源 HTTP 负载均衡支持基于实际请求结果的被动健康判断,例如根据连续失败次数和时间窗口把服务器暂时标记为不可用。

主动检查

负载均衡器定期主动访问:

/health

或者探测:

TCP 端口

但“端口可以连接”并不一定代表业务完全健康。

因此健康检查需要明确层次:

TCP 连接成功
HTTP 返回成功
依赖服务正常
业务可处理

检查越深入,成本和误判风险也越高。


十二、会话怎么办?

如果用户登录状态只保存在某一台服务器内存:

第一次请求
    → Server A
    → 创建 Session

第二次请求
    → Server B
    → 找不到 Session

常见方案有三种。

粘性会话

尽量把同一用户送到同一节点:

client IP hash
Cookie hash

Nginx 的 ip_hash 可以基于客户端 IP 选择服务器,实现一定程度的稳定映射。

缺点是:

节点故障时会话仍可能丢失
负载容易不均
扩缩容影响映射

共享状态

把 Session 放入:

Redis
数据库
分布式缓存

后端节点尽量保持无状态。

客户端携带状态

例如:

签名 Token

但仍需要处理:

撤销
过期
权限变化
密钥轮换

负载均衡不能自动解决业务状态管理。


十三、四层还是七层?

可以从几个维度选择。

维度四层七层
典型决策IP、端口、连接Host、Path、Header、Cookie
调度粒度连接请求
协议理解较少需要理解应用协议
自定义二进制协议很适合需要对应应用层支持
URL 路由不直接支持支持
Header 修改不直接支持支持
TLS 透传适合不能读取明文 HTTP
缓存与 WAF不适合适合
实现开销通常更低功能更多、处理更深

但这不是绝对性能结论。

真实性能取决于:

实现方式
硬件
内核旁路
连接数量
TLS
报文大小
请求复杂度
缓存命中
业务延迟

“层数更低”通常意味着需要理解的信息更少,但并不保证任何场景都更快。


十四、常见组合

生产系统常常不是二选一,而是组合使用:

客户端
    ↓
DNS / 全局流量调度
    ↓
四层负载均衡
    ↓
七层反向代理
    ↓
应用网关
    ↓
微服务

例如:

四层
    负责把大量 TCP 连接分散到多台代理

七层
    根据 Host、Path 和 Header 分发请求

服务网关
    负责认证、限流和路由

服务端
    执行业务

这样每层都承担最适合自己的职责。


十五、常见误区

1. 多加几台服务器就完成负载均衡

错误。

还需要统一入口和流量选择机制。

2. 负载均衡等于高可用

错误。

负载均衡器本身也可能成为单点。

3. 四层一定不建立 TCP 连接

错误。

IPVS 等可以做数据包转发,Nginx Stream 等也可以作为 TCP 代理。

4. 四层能按 URL 转发

典型情况下不能。

URL 属于 HTTP 应用层语义。

5. 七层只看端口

错误。

七层可以读取 Host、Path、Header 等应用信息。

6. 四层一定比七层快

不严谨。

四层通常处理更少的协议信息,但最终性能仍取决于具体实现和场景。

7. HTTPS 无法负载均衡

错误。

可以做 TLS 透传,也可以在代理处终止 TLS 后进行七层路由。

8. 有 requestId 就可以按请求做四层调度

错误。

除非设备理解并解析对应应用协议,否则它无法使用业务 requestId。

9. 最少连接一定最均衡

错误。

连接数量不一定代表请求成本。

10. IP Hash 能保证会话永不丢失

错误。

节点故障、扩缩容、客户端出口变化都会影响映射。

11. 健康检查成功代表业务完全正常

错误。

TCP 端口可连接不代表数据库、线程池和核心业务都健康。

12. 七层代理会复用客户端原始 TCP 连接到后端

典型反向代理不会。

它通常维护客户端侧连接和后端侧连接两套通道。


总结

服务器从一台增加到多台后,需要一个统一入口:

客户端
    ↓
负载均衡器
    ↓
后端集群

四层负载均衡主要依据:

协议
IP
端口
连接状态

典型调度粒度是:

连接

一条连接被选到某台后端后,后续数据通常继续交给该后端。

七层负载均衡理解 HTTP 等应用协议,可以依据:

Host
Path
Method
Header
Cookie

进行调度。

它的粒度可以是:

请求

四层实现可能是:

NAT
Direct Routing
Tunneling
TCP Proxy

所以四层不等于“永远不终止连接”。

七层代理通常会形成:

客户端连接
    ↓
代理
    ↓
后端连接

HTTPS 则需要在两种模式中选择:

TLS 透传
    不能读取完整 HTTP

TLS 终止
    可以进行七层路由

最终选择不应该只看“哪一层更高级”,而应该看:

需要读取哪些信息
按连接还是按请求调度
是否需要 TLS 透传
是否需要缓存、鉴权和重写
是否需要支持自定义协议

最后,可以用一句话概括四层与七层的区别:

四层主要决定一条连接交给哪台服务器,七层则能理解连接中的应用请求,并决定每个请求应该进入哪条业务链路。

0

评论区