D
Backend network request laboratory

计算机网络不是背八股,而是看懂一次请求如何穿过互联网

从输入 URL 到页面显示,用动画拆开 DNS、TCP、TLS、HTTP、Go 服务端与网络排障。

01这道网络问题在问什么
02它发生在请求链路的哪一层
03系统内部状态怎么变化
04面试怎么回答,线上怎么排查
Request path

Browser -> DNS -> TCP -> TLS -> HTTP -> Go Server -> RPC/DB/Cache -> Troubleshooting

curl -w 'dns=%{time_namelookup}
tcp=%{time_connect}
tls=%{time_appconnect}
ttfb=%{time_starttransfer}
total=%{time_total}' https://api.example.com/orders/42
interviewer sidebar

先问:这一步的 observable 是什么?

再问:状态变量在哪,队列在哪,超时在哪?

最后问:你用什么命令证明它?

interactive knowledge map

交互式思维导图:所有知识点都围绕一次 URL 请求

未学习正在学习已掌握高频面试
flagship animation

URL Request Simulator:从输入 URL 到页面显示

1 / 7
浏览器

地址栏 / 缓存 / Socket / Renderer

地址栏
DNS Cache
Socket Pool
HTTP Request Builder
Renderer
网络世界

DNS / CDN / Router / Internet Packet Path

Local DNS
Root DNS
TLD DNS
Authoritative DNS
CDN Node
Router
Internet Packet Path
绿色加密隧道
服务器机房

LB / Nginx / Go / Redis / MySQL

Load Balancer
Nginx
Go HTTP Server
Redis
MySQL
Server Kernel
SYN Queue
Accept Queue
packet path
正常模式慢速讲解模式
URL 还在浏览器内部拆解,暂时没有网络包。
TCP connection simulator

TCP 三次握手模拟器:包、状态机、SYN Queue、Accept Queue 同步推进

正常路径、SYN+ACK 丢失、SYN Flood、Accept Queue 满四种场景都能逐帧暂停,右侧解释面板回答真实面试追问。

RuntimeScope / 计算机网络高级面试专题 / Ch03

TCP 三次握手 · SYN/Accept Queue

CLOSED → SYN-SENT / SYN-RECV → ESTABLISHED

真实问题 · 为什么 TCP 是三次握手,不是两次也不是四次?

旗舰动画
面试官追问链
  1. 01 SYN queue 和 accept queue 区别是什么?满了会怎样?
  2. 02 backlog 调小会出什么现象?
  3. 03 SYN flood 攻击下半连接怎么变化?SYN cookie 怎么解?
  4. 04 ISN(初始序列号)是怎么选的?为什么不能固定?
场景
正常路径
网络包飞行层

当前网络包、方向、flags、seq/ack 和丢包/重传命运

(no packet on wire)
当前网络包
no packet on wire
TCP 状态机层

Client / Server 状态与本帧 seq、ack 同步变化

Client 状态
CLOSED
seq
1000
ack
0
Server 状态
LISTEN
seq
0
ack
0
内核队列层

半连接在 SYN queue,全连接在 accept queue,Go accept() 只消费后者

SYN queue · 半连接
刚收到 SYN,等 client ACK
0 / 4
accept queue · 全连接
ESTABLISHED,等应用 accept()
0 / 4
应用层 · Go accept() / handler

业务代码何时能看到连接,为什么握手完成不等于 handler 已执行

Go accept()

accept() 阻塞等待新连接

handler

handler 未启动

code / queue effect
net/http Serve loop 等待内核交付连接

SYN queue 和 accept queue 都为空

类比像快递发件前先给包裹一个唯一编号,方便后续对账。
TCP1 / 7
production incident simulator

线上事故模拟器:现象 -> 猜测 -> 工具 -> 证据 -> 修复

进入排障实验

接口突然变慢

现象P99 从 120ms 飙到 3s,错误率不高,业务日志只看到 handler 变慢。
猜测先不要猜数据库,按 DNS/TCP/TLS/应用/下游分层看耗时桶。
工具curl -w、OpenTelemetry trace、pprof、tcpdump
证据time_starttransfer 高,trace 显示 cache miss 后 RPC deadline 被吃完。
修复拆分 timeout budget,给 cache miss 降级,慢查询和连接池分别限流。

大量 TIME_WAIT

现象ss -tan 看到 TIME_WAIT 快速增长,短连接压测后端口耗尽。
猜测主动关闭方在等 2MSL,通常是客户端短连接或服务端主动断开。
工具ss -tan state time-wait、netstat -s、连接复用指标
证据同一 client IP 短时间创建大量新连接,HTTP keep-alive 命中率很低。
修复复用连接池,调大本地端口范围,减少主动关闭,谨慎评估内核参数。

大量 CLOSE_WAIT

现象服务进程 FD 持续上涨,CLOSE_WAIT 堆积,重启后短暂恢复。
猜测对端已经发 FIN,本进程没有 close socket,常见于 resp.Body 未关闭。
工具lsof、ss -tanp、pprof goroutine、代码审计
证据CLOSE_WAIT 都挂在同一进程,goroutine 堆栈停在读取响应体路径。
修复确保 Body close/drain,设置超时,压测验证 FD 和连接状态回落。

DNS 偶发超时

现象部分地区偶发解析慢,服务端没有请求日志,重试后恢复。
猜测请求没到业务服务,优先看本地缓存、递归解析器、权威 DNS、CDN 调度。
工具dig +trace、mtr、浏览器 netlog、递归 DNS 监控
证据特定运营商 recursive 到权威链路超时,浏览器 waterfall 卡在 DNS。
修复缩短故障域 TTL,切换权威 DNS 调度,增加多递归 fallback。

WebSocket 经常断开

现象移动端切网或静置几分钟后断开,服务端没有明显错误。
猜测长连接被 LB/NAT idle timeout 回收,或心跳间隔大于中间设备阈值。
工具tcpdump、LB 日志、客户端网络事件、ping/pong 指标
证据断开前没有业务帧,LB idle timeout 与断开时间吻合。
修复心跳间隔小于 idle timeout,补断线重连、会话恢复和消息 ACK 补偿。

重试风暴

现象下游轻微抖动后 QPS 被放大,超时、限流和错误率一起上升。
猜测客户端同步重试把故障放大,缺少 jitter、预算和熔断。
工具trace fan-out、retry count 指标、限流日志、熔断状态
证据同一请求链路出现多次重试,retry burst 与下游 P99 同步上升。
修复加 timeout budget、指数退避+jitter、幂等键、熔断和按调用方限流。
source lock

引用台账:关键结论绑定到可点击 RFC source card