跳转至

网络分层模型

学习目标

学完本章后,学习者应该能够:

  1. 理解 OSI 七层模型和 TCP/IP 四层模型的用途。
  2. 解释封装与解封装的基本过程。
  3. 知道一次 HTTP 请求大致经过哪些层。
  4. 能把常见网络问题归类到大致层级。

为什么需要分层

网络很复杂,分层的目的不是制造术语,而是把职责拆开:

层次 解决的问题 后端常见关注点
应用层 应用协议和业务语义 HTTP、gRPC、DNS
传输层 端到端传输 TCP、UDP、端口、连接
网络层 主机到主机寻址和路由 IP、路由、NAT
链路层 同一链路内传输 MAC、ARP、网卡

OSI 七层模型更适合理解概念,TCP/IP 四层模型更贴近日常工程。

封装与解封装

发送数据时,每一层都会加上自己的头部信息:

HTTP 数据 -> TCP 段 -> IP 包 -> 以太网帧

接收时反过来逐层拆开:

以太网帧 -> IP 包 -> TCP 段 -> HTTP 数据

如果你看到“连接超时”,问题可能发生在 DNS、路由、TCP 握手、防火墙、服务监听、负载均衡等多个环节。分层能帮助我们缩小范围。

一次 HTTP 请求的简化路径

sequenceDiagram
    participant Client as Client
    participant DNS as DNS
    participant LB as Load Balancer
    participant Server as Go Server
    Client->>DNS: 查询域名
    DNS-->>Client: 返回 IP
    Client->>LB: 建立 TCP 连接
    Client->>LB: TLS 握手
    Client->>LB: 发送 HTTP 请求
    LB->>Server: 转发请求
    Server-->>LB: 返回响应
    LB-->>Client: 返回响应

每一步都有可能慢或失败。

Go 后端实际应用例子

例子一:用 httptrace 观察请求阶段

Go 的 net/http/httptrace 可以观察 DNS、连接、TLS 等阶段:

trace := &httptrace.ClientTrace{
    DNSStart: func(info httptrace.DNSStartInfo) {
        log.Printf("dns start: %s", info.Host)
    },
    ConnectStart: func(network, addr string) {
        log.Printf("connect start: %s %s", network, addr)
    },
    GotFirstResponseByte: func() {
        log.Printf("first response byte")
    },
}

req, err := http.NewRequest(http.MethodGet, "https://example.com", nil)
if err != nil {
    return err
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
_, err = http.DefaultClient.Do(req)

这类工具能把“请求慢”拆成更具体的网络阶段。

例子二:按层定位问题

如果接口访问失败,可以先粗略归类:

  • 域名无法解析:DNS 层面。
  • 能解析但连接超时:网络层、传输层或防火墙。
  • TCP 连接成功但 TLS 失败:TLS 配置、证书或 SNI。
  • TLS 成功但 HTTP 5xx:应用层或上游服务。

常见误区

  • 误区一:网络分层只是考试内容。

分层是排障工具。它能帮助你快速判断该看 DNS、TCP、TLS、HTTP 还是应用日志。

  • 误区二:HTTP 慢一定是服务端代码慢。

慢可能发生在 DNS、建连、TLS、排队、代理转发、响应读取或客户端连接池。

  • 误区三:能 ping 通就说明 HTTP 一定能访问。

ping 使用 ICMP,HTTP 使用 TCP。防火墙、端口、代理、TLS 都可能让 HTTP 失败。

线上问题案例

某服务访问第三方 API 偶发慢。业务日志只记录总耗时,无法判断慢在下游处理还是网络阶段。接入 httptrace 后发现慢主要发生在 DNS 查询阶段,进一步定位到本地 DNS 缓存不稳定。

修复方式包括增加 DNS 指标、调整 resolver、复用连接、降低每次请求重新解析域名的概率。

实战任务

画出一次 https://api.example.com/users 请求的路径,并标出可能失败的阶段:

  1. DNS 解析。
  2. TCP 建连。
  3. TLS 握手。
  4. HTTP 请求发送。
  5. 服务端处理。
  6. 响应读取。
参考答案

可以按“客户端 -> DNS -> 负载均衡 -> 网关或反向代理 -> Go 服务 -> 数据库或缓存 -> Go 服务 -> 客户端”画路径。DNS 阶段可能解析失败或慢;TCP 阶段可能连接超时、端口不通或被防火墙拦截;TLS 阶段可能证书过期、SNI 错误或协议不兼容。

HTTP 阶段可能出现 4xx、5xx、请求体过大、代理超时;服务端处理阶段可能是数据库慢、锁竞争、CPU 或内存压力;响应读取阶段可能因为客户端读得慢或连接被重置失败。

面试题

1. 为什么网络要分层?

参考答案

分层能把复杂网络问题拆成职责清晰的部分。链路层负责同一链路内传输,网络层负责寻址和路由,传输层负责端到端传输,应用层负责具体协议语义。

对后端工程师来说,分层能帮助排障。例如 DNS 失败、TCP 连接失败、TLS 失败和 HTTP 5xx 属于不同层面,排查工具和负责人都可能不同。

2. TCP/IP 四层模型包括哪些层?

参考答案

常见 TCP/IP 四层模型包括应用层、传输层、网络层和网络接口层。应用层包括 HTTP、DNS、gRPC 等;传输层包括 TCP 和 UDP;网络层主要是 IP 和路由;网络接口层对应以太网、Wi-Fi、ARP 等底层链路能力。

3. ping 通但 HTTP 不通可能是什么原因?

参考答案

ping 使用 ICMP,只能说明到目标地址的某些网络路径可能可达。HTTP 还依赖 TCP 端口、服务监听、负载均衡、防火墙、TLS、Host、代理和应用逻辑。

因此 ping 通不能证明 HTTP 一定可用;HTTP 不通时还要用 curl、telnet/nc、ss/netstat、服务日志和代理日志继续排查。