NETWORK · HTTP / TCP / DNS 协议
网络协议速查
从 HTTP 版本演进到 TCP 三次握手与四次挥手,从 DNS 递归解析到 gRPC、GraphQL 的选型对比,一页理清网络协议核心概念。
12速查小节
12+主流协议
58+核心知识点
📖 速查表
点击展开各小节
📡 协议对比总览
| 协议 | 层级 | 传输方式 | 特点 | 典型场景 |
|---|---|---|---|---|
| HTTP/1.1 | 应用层 | TCP | 文本协议,队头阻塞(HOL),每个请求/响应占用一个连接或通过 Keep-Alive 复用 | 传统 Web 页面、RESTful API |
| HTTP/2 | 应用层 | TCP | 二进制分帧、多路复用(同一连接多个流)、服务器推送、头部压缩(HPACK) | 现代 Web 应用、SPA 加载优化 |
| HTTP/3 | 应用层 | QUIC (UDP) | 基于 QUIC(UDP 之上),0-RTT 连接建立、多路复用无队头阻塞、更好的弱网表现 | 实时应用、移动端弱网环境 |
| WebSocket | 应用层 | TCP | 全双工通信,通过 HTTP 升级(101 Switching Protocols),持久连接 | 实时聊天、推送服务、在线游戏、协同编辑 |
| TCP | 传输层 | 面向连接 | 面向连接、可靠传输(确认重传)、流量控制(滑动窗口)、拥塞控制(慢开始、拥塞避免) | Web 浏览、文件传输、邮件等绝大多数网络应用 |
| UDP | 传输层 | 无连接 | 无连接、不可靠但低延迟、无拥塞控制、支持广播/多播 | DNS 查询、视频直播、语音通话、在线游戏 |
| DNS | 应用层 | UDP(主)+ TCP | 域名解析系统,将域名映射为 IP 地址。UDP 53 端口为主,大响应时使用 TCP | 浏览器地址栏输入后发起的第一个网络请求 |
| gRPC | 应用层 | HTTP/2 | 基于 HTTP/2 的高性能 RPC 框架,使用 Protocol Buffers 序列化,支持双向流 | 微服务间通信、多语言交互、流式数据传输 |
| GraphQL | 应用层 | HTTP | 查询语言 + 运行时,客户端精确指定所需字段,避免过度获取或获取不足 | 复杂数据聚合、BFF 层、移动端 API |
🌐 HTTP 协议版本演进
HTTP/1.1 (1997)
持久连接 Keep-Alive 复用
管道化 理论上可并行但实际困难
队头阻塞 一个请求阻塞整个连接
文本协议 可读性好但效率低
管道化 理论上可并行但实际困难
队头阻塞 一个请求阻塞整个连接
文本协议 可读性好但效率低
HTTP/2 (2015)
二进制分帧 效率更高
多路复用 同一连接多个流
服务器推送 主动推送资源
头部压缩 HPACK 降体积 80%+
多路复用 同一连接多个流
服务器推送 主动推送资源
头部压缩 HPACK 降体积 80%+
HTTP/3 (2022)
基于 QUIC 底层使用 UDP
0-RTT 连接建立几乎零延迟
无队头阻塞 丢包只影响单个流
内核无关 用户空间实现,易升级
0-RTT 连接建立几乎零延迟
无队头阻塞 丢包只影响单个流
内核无关 用户空间实现,易升级
🔄 TCP 与 UDP 对比
TCP(传输控制协议)
✅ 面向连接 — 三次握手建立连接
✅ 可靠传输 — 确认机制 + 超时重传
✅ 流量控制 — 滑动窗口
✅ 拥塞控制 — 慢开始 / 拥塞避免 / 快重传 / 快恢复
✅ 有序交付 — 接收端重新排序
❌ 头部较大(20-60 字节)
❌ 连接延迟(三次握手)
❌ 队头阻塞问题
✅ 可靠传输 — 确认机制 + 超时重传
✅ 流量控制 — 滑动窗口
✅ 拥塞控制 — 慢开始 / 拥塞避免 / 快重传 / 快恢复
✅ 有序交付 — 接收端重新排序
❌ 头部较大(20-60 字节)
❌ 连接延迟(三次握手)
❌ 队头阻塞问题
UDP(用户数据报协议)
✅ 无连接 — 直接发送,延迟低
✅ 不可靠 — 无确认重传,适合实时
✅ 头部小(8 字节)
✅ 支持广播和多播
✅ 无拥塞控制
⚠️ 不保证有序交付
⚠️ 可能丢包、重复
⚠️ 应用层需自己处理可靠性
✅ 不可靠 — 无确认重传,适合实时
✅ 头部小(8 字节)
✅ 支持广播和多播
✅ 无拥塞控制
⚠️ 不保证有序交付
⚠️ 可能丢包、重复
⚠️ 应用层需自己处理可靠性
🔗 gRPC 核心概念
| 概念 | 说明 |
|---|---|
| Protocol Buffers | 接口定义语言(IDL),定义服务和消息类型。比 JSON 更小更快,二进制序列化格式 |
| Unary RPC | 客户端发送单个请求,服务器返回单个响应。类似传统 HTTP API 调用 |
| Server Streaming | 客户端发送单个请求,服务器返回流式响应。适用于推送、实时数据 |
| Client Streaming | 客户端发送流式请求,服务器返回单个响应。适用于上传大文件、批量数据 |
| Bidirectional Streaming | 客户端和服务器同时双向发送流式数据。适用于实时交互场景 |
| HTTP/2 底层 | gRPC 基于 HTTP/2 多路复用、双向流、头部压缩特性,性能优于 REST |
📊 GraphQL vs REST
| 维度 | REST | GraphQL |
|---|---|---|
| 数据获取 | 固定结构,多端点,常需多次请求 | 单一端点,客户端精确指定所需字段 |
| 过度/不足获取 | 常见问题(over-fetching / under-fetching) | 按需获取,不多不少 |
| 版本管理 | 通常靠 URL 路径版本化(/v1/, /v2/) | 渐进式演进,字段可弃用但不断开 |
| 缓存策略 | 天然支持 HTTP 缓存(GET 缓存) | 查询都是 POST,需额外实现缓存层 |
| 学习曲线 | 低,HTTP 语义通用 | 中等,需理解 Schema、Resolver、DataLoader |
| 工具生态 | 成熟(Postman、cURL) | GraphiQL、Apollo DevTools、Hasura |
🔍 DNS 解析流程
域名解析失败或被劫持时,按这条链路从上往下逐级排查:本地缓存 → 本地 DNS → 根 → 顶级域 → 权威服务器。
浏览器输入 https://www.example.com
1. 浏览器缓存查询 — 是否已有该域名的 IP?
2. 操作系统缓存查询(/etc/hosts 或系统 DNS 缓存)
3. 本地 DNS 服务器(通常是 ISP 或 8.8.8.8)
└─ 递归查询
4. 根域名服务器(.) → 返回 .com 顶级域名服务器地址
5. .com 顶级域名服务器 → 返回 example.com 权威域名服务器地址
6. example.com 权威服务器 → 返回 www.example.com 的 IP 地址(A/AAAA 记录)
7. 本地 DNS 服务器缓存结果并返回给客户端
8. 浏览器拿到 IP 地址,发起 TCP 连接(HTTP 请求)
🤝 TCP 三次握手与四次挥手
三次握手(建立连接)
① 客户端 → 服务器:SYN=1, Seq=x
② 服务器 → 客户端:SYN=1, ACK=1, Seq=y, Ack=x+1
③ 客户端 → 服务器:ACK=1, Seq=x+1, Ack=y+1
为什么不是 2 次? 防止已失效的连接请求传送到服务器导致错误
② 服务器 → 客户端:SYN=1, ACK=1, Seq=y, Ack=x+1
③ 客户端 → 服务器:ACK=1, Seq=x+1, Ack=y+1
为什么不是 2 次? 防止已失效的连接请求传送到服务器导致错误
四次挥手(断开连接)
① 客户端 → 服务器:FIN=1, Seq=u
② 服务器 → 客户端:ACK=1, Seq=v, Ack=u+1
③ 服务器 → 客户端:FIN=1, ACK=1, Seq=w, Ack=u+1
④ 客户端 → 服务器:ACK=1, Seq=u+1, Ack=w+1
TIME_WAIT 等待 2MSL 确保对方收到关闭确认
② 服务器 → 客户端:ACK=1, Seq=v, Ack=u+1
③ 服务器 → 客户端:FIN=1, ACK=1, Seq=w, Ack=u+1
④ 客户端 → 服务器:ACK=1, Seq=u+1, Ack=w+1
TIME_WAIT 等待 2MSL 确保对方收到关闭确认
🔐 HTTPS 与 TLS
HTTPS = HTTP + TLS:面试问「为什么安全」时,抓住非对称协商密钥、对称加密传数据、证书验身份这三点即可展开。
| 要点 | 说明 | 细节 / 示例 |
|---|---|---|
| 混合加密思想 | 非对称加密只用于协商对称密钥,数据传输用对称加密,兼顾安全与性能 | RSA/ECDHE 交换密钥 → AES-GCM 加密报文 |
| TLS 1.2 握手 | 需 2-RTT:协商套件 → 服务器发证书与密钥交换 → 客户端密钥材料 → 双方校验 Finished | ClientHello → ServerHello + Certificate → ClientKeyExchange → ChangeCipherSpec + Finished |
| 证书链校验 | 沿「站点证书 → 中间 CA → 根 CA」逐级验签,根证书信任来源为系统内置信任库 | 任一环节过期、域名不匹配或被吊销(CRL/OCSP)即告警拦截 |
| TLS 1.3 握手 | 压缩到 1-RTT:客户端在 ClientHello 直接带上密钥共享材料;会话恢复可 0-RTT | 握手期间大部分参数已加密,中间人可见信息更少 |
| 1.2 vs 1.3 套件 | 1.3 删除 RSA 密钥交换与 CBC 套件,仅保留 AEAD 加密 + ECDHE 密钥协商 | 更少 RTT、防降级、历史流量不可回解 更快更安全 |
| 前向安全 | 每次会话使用临时密钥,服务器私钥泄露也无法解密历史流量 | 依赖 ECDHE 临时密钥协商;建议全站启用 推荐开启 |
🔌 WebSocket 与推送
| 方式 | 通信模型 | 特点 / 适用场景 |
|---|---|---|
| 短轮询 | 客户端定时重复发起请求,服务端即问即答 | 实现最简单;延迟高、无效请求多,适合状态更新频率低的页面 |
| 长轮询 | 请求挂起直到有数据或超时,返回后立刻再次发起 | 实时性优于轮询;仍占连接,兼容性好(早期推送方案) |
| SSE | 基于 HTTP 的服务端单向流式推送(text/event-stream) | 只能服务器→客户端;自带断线重连与事件类型,适合行情、日志、进度条 |
| WebSocket | HTTP 升级为全双工长连接,双向实时通信,持久连接 | 聊天、协同编辑、在线游戏、实时推送;需自行实现重连与心跳 |
| 握手升级 | 普通 GET 请求携带升级头,服务器返回 101 Switching Protocols 后切换协议 | Upgrade: websocket + Connection: Upgrade + Sec-WebSocket-Key |
| 心跳保活 | 定期 ping/pong 探活,及时清理半开连接并维持链路 | 间隔约 20~30 s;可穿透代理/防火墙,避免空闲断连 长连接必备 |
🌍 从输入 URL 到页面
| 阶段 | 说明 |
|---|---|
| ① URL 解析 | 浏览器补全协议、拆出域名/端口/路径,检查 HSTS 与本地缓存,决定是否发起网络请求 |
| ② DNS 解析 | 浏览器缓存 → 系统缓存 → 本地 DNS 服务器递归查询,最终拿到服务器 IP 地址 |
| ③ TCP 连接 | 与服务器三次握手建立可靠通道;HTTP/3 走 QUIC(UDP),传输与握手合二为一 |
| ④ TLS 握手 | HTTPS 场景协商加密套件与对称密钥(TLS 1.2 两次往返 / 1.3 一次往返) |
| ⑤ 发送 HTTP 请求 | 构造请求行、头部与请求体发出;Keep-Alive / HTTP 2 多路复用可跳过 ③④ 直接复用连接 |
| ⑥ 服务端处理 | 负载均衡 → 网关 → 应用逻辑 → 缓存/数据库,组装响应报文按原路返回 |
| ⑦ 浏览器渲染 | 解析 HTML 建 DOM、CSS 建 CSSOM → 合成渲染树 → 布局(重排)→ 绘制(重绘)→ 合成显示 |
| ⑧ 连接复用收尾 | 静态资源命中强缓存/协商缓存直接本地加载;后续请求复用长连接减少握手开销 |
🚦 抓包与流量观察
排查网络问题先「看见流量」:从链路质量到 TCP 握手再到应用响应,按这条观测链逐段缩小范围,比凭感觉猜快得多。
| 命令 / 工具 | 用途 | 要点 / 示例 |
|---|---|---|
| tcpdump -i any port 8080 -w a.pcap | 抓指定端口的原始报文存盘,留给 Wireshark 离线细看 | -i any 覆盖所有网卡不漏包;生产机只抓不读,避免现场翻屏影响他人 起手式 |
| tcpdump -nn host 10.0.0.2 and port 443 | 按 IP 与端口精确过滤,快速锁定目标会话 | -nn 不做域名/协议反解,速度快也不引入反向 DNS 流量;多条件用 and / or / not 组合 |
| Wireshark:http / tcp.flags.syn==1 | 图形化分析 pcap:还原会话、看握手时序与重传 | 显示过滤器与抓包 BPF 语法不同,别混用;tcp.flags.syn==1 && tcp.flags.ack==0 定位握手第一步;Follow TCP Stream 还原整段对话 |
| curl -v https://example.com | 最小成本复现一次完整请求,逐阶段看卡在哪 | 输出依次是 DNS → TCP → TLS → 响应头;配合 -w '%{time_connect} %{time_appconnect}' 把握手耗时拆开量化 分段定位 |
| ss -s | 连接状态总览,一眼看出各 TCP 状态的数量分布 | TIME_WAIT 偏高多是短连接过多;再用 ss -antp 按状态细分,定位到具体进程 |
| ping -i 0.5 -c 10 host | 控制间隔与次数探测连通性、延迟与抖动 | 默认 1s 间隔太慢可调小;注意禁 ICMP 的网络里 ping 不通 ≠ 服务不可用,改用 curl 验证端口 易误判 |
| mtr -r host | ping + traceroute 合体,输出路径级丢包报告 | 读法:中间节点 Loss% 高而末端不高,多为路由器限制 ICMP;末端持续丢包/高延迟才是真问题 报告解读 |
🩺 连接异常排查对照
六类最常见的连接异常:先分清是「正常现象但量太大」还是「代码缺陷」,再决定调参数还是改代码,方向错了白忙一场。
| 现象 | 常见原因 | 处理思路 |
|---|---|---|
| TIME_WAIT 巨多 | 本端主动关闭且短连接泛滥:每次请求新建连接、健康检查高频触发 | 优先复用:HTTP Keep-Alive、连接池、长连接客户端;客户端方向可开 tcp_tw_reuse;先问「为什么要建这么多短连接」再调内核 先复用后调参 |
| CLOSE_WAIT 堆积 | 对端已发 FIN,本端应用一直不调 close——几乎都是连接泄漏的代码 Bug | ss -antp 找到进程,排查异常分支漏关、连接池未归还;调内核参数无效,必须改代码 代码问题 |
| Connection refused | 目标端口无进程监听(内核以 RST 应答 SYN),或防火墙策略 REJECT | ss -lntp 确认端口监听;本机与容器环境常见只监听 127.0.0.1 未监听 0.0.0.0 |
| 随机 RST / 间歇重置 | 中间设备清会长连接:负载均衡 idle 超时、NAT 会话过期、防火墙状态超时 | 抓包确认 RST 由谁发出;客户端心跳间隔必须小于链路上最短的超时;重试逻辑保证幂等 长连接必备 |
| 丢包重传(延迟毛刺) | 弱网、交换机缓冲排队、接收窗口不足触发重传 | ss -ti 看单连接的 retrans 指标;mtr 定位丢包跳点;应用层表现是 P99 飙高而均值正常 盯长尾 |
| 端口不通 | 安全组/iptables 未放行、服务未启动、监听地址绑错 | 分段验证缩小范围:本机 curl 127.0.0.1:端口 → 同网段 → 跨网段;云上依次查安全组与子网 ACL 两层 |