大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
网络基础
这一课你将能做到
- 画出一次 HTTPS 请求的完整链路:DNS → TCP 三次握手 → TLS 握手 → HTTP 请求 → 响应
- 用 curl、ping、telnet、dig 四个命令定位「网站打不开」的故障层
- 配置本站的 Nginx 反向代理:负载均衡、TLS 终止、超时与缓冲
为什么要学
线上问题里至少一半是网络问题,而网络问题的排查完全依赖分层思维。「接口超时」可能是 DNS 解析慢、TCP 握手失败、TLS 证书过期、网关超时、后端真的慢——不懂网络分层,你只能重启碰运气。
人话:网络分层像快递系统。你寄一个包裹(HTTP 请求),快递单写的是收件人域名(DNS 查地址),卡车运输要保证不丢件(TCP),贵重物品要保险箱(TLS 加密),最后驿站代收分发(反向代理)。
先建立图像
OSI 七层与实际协议对照:
OSI 七层 TCP/IP 四层 本站实际组件
─────────────────────────────────────────────
7 应用层 ┐
6 表示层 ├─→ 应用层 HTTP / DNS / TLS
5 会话层 ┘
4 传输层 ──→ 传输层 TCP / UDP(端口在这里)
3 网络层 ──→ 网络层 IP / ICMP(ping 在这层)
2 数据链路层 ┐
1 物理层 ┴─→ 链路层 网卡 / 交换机
一次请求的封装过程:
[HTTP 数据] → +TCP头(端口) → +IP头(地址) → +MAC头(网卡) → 网线
跟着做
步骤 1:逐层排查「本站打不开」
# 第一层:DNS 解析是否正常?
dig coderoadmap.cn
# 期望看到 A 记录指向正确 IP。失败 → DNS 配置/本地 hosts 问题
# 第二层:网络可达吗?
ping 47.x.x.x
# 不通 → 网络链路/防火墙/安全组问题
# 第三层:端口通吗?
telnet 47.x.x.x 443
# 不通 → 服务没监听/防火墙拦截/安全组没放行 443
# 第四层:HTTP 层面什么响应?
curl -v https://coderoadmap.cn/api/health
# -v 显示完整握手过程,能看到 TLS 版本、证书、响应头、耗时分布
curl -v 输出里藏着金矿:Connected to 前是 TCP 耗时,SSL handshake 是 TLS 耗时,> 开头是发出的请求,< 开头是收到的响应。
步骤 2:理解 TCP 三次握手(面试必考)
客户端 服务端
│ ──── SYN(seq=x) ────────────→ │ 「我想连接,序号从 x 开始」
│ ←── SYN+ACK(seq=y,ack=x+1) ── │ 「好的,我的序号 y,期待你的 x+1」
│ ──── ACK(ack=y+1) ──────────→ │ 「确认,开始传数据」
为什么是三次不是两次?
两次无法防止「历史失效连接」:客户端发的第一个 SYN 在网络里迷路,
客户端超时重发并完成了通信;之后迷路的 SYN 又到达服务端——
如果两次握手,服务端会为这个失效 SYN 白白建立连接浪费资源。
步骤 3:配置本站 Nginx 反向代理
upstream backend {
least_conn; # 最少连接数算法
server 10.0.1.11:8080 max_fails=3; # 失败 3 次摘除
server 10.0.1.12:8080 max_fails=3;
keepalive 32; # 到后端的长连接池
}
server {
listen 443 ssl;
server_name coderoadmap.cn;
ssl_certificate /etc/nginx/cert.pem;
ssl_certificate_key /etc/nginx/key.pem;
ssl_protocols TLSv1.2 TLSv1.3; # 禁用过时协议
location /api/ {
proxy_pass http://backend;
proxy_connect_timeout 3s; # 连接后端超时
proxy_read_timeout 30s; # 等后端响应超时
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
讲清楚要点
- 分层思维是排查的第一原则:先确定故障在哪一层,再深入。DNS 不通查 IP 没意义,TCP 不通发 HTTP 请求没意义。每层的排查工具不同:dig(DNS)、ping/traceroute(网络层)、telnet/ss(传输层)、curl(应用层)。
- TCP 的可靠性是有代价的:三次握手(1 个 RTT)+ 慢启动,短连接场景开销巨大。所以 HTTP/1.1 有 keep-alive 复用连接,HTTP/2 多路复用,HTTP/3 干脆换 QUIC(UDP 之上自建可靠性)。
- TLS 保护三样东西:机密性(内容加密)、完整性(防篡改)、身份认证(证书证明你确实是 coderoadmap.cn)。证书过期是线上高频事故,必须监控自动续期。
- 反向代理 vs 正向代理:正向代理站在客户端这边(科学上网工具);反向代理站在服务端这边(Nginx),客户端不知道后端真实地址。负载均衡、TLS 终止、静态资源、缓存都是反向代理的职责。
- 超时是网络编程的头等大事:不设超时的请求会在线程池耗尽后拖垮整个服务。原则:每一层都要有超时,且下游超时 < 上游超时(否则上游已放弃,下游还在干)。
你可能会懵的地方
-
TCP 三次握手我能背,但为什么实际 curl 很快? 因为有连接复用。第一次完整握手后,连接保持(keep-alive),后续请求直接复用,零握手开销。浏览器还会对同一域名开多个并发连接。
-
TLS 握手要交换证书,不是更慢吗? TLS 1.2 要 2 个 RTT,TLS 1.3 只要 1 个 RTT(且支持 0-RTT 恢复会话)。加上会话复用,实际开销很小。这也是本站要求 TLS 1.3 的原因。
-
长连接和短连接怎么选? 应用内部服务调用:长连接(gRPC 天然支持)。对外 HTTP API:keep-alive 即可。数据库连接:连接池本质就是长连接管理。短连接只适合极低频、无状态的场景。
-
负载均衡有哪些算法? 轮询(均分)、加权轮询(按机器性能分)、最少连接(本站采用,适合请求耗时不均)、IP 哈希(同一客户端固定到一台,可保持会话亲和)。没有最好的,看流量特征。
-
防火墙和安全组什么关系? 安全组是云厂商提供的虚拟防火墙,工作在实例/网卡级别;iptables/firewalld 是操作系统内防火墙。流量要过两道:安全组 → 系统防火墙 → 应用监听。排查端口不通时两层都要查。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| HTTP 客户端不设超时 | 下游挂了拖死自己线程池 | 连接超时 + 读超时都设,宁短勿长 |
| 上游超时 < 下游超时 | 上游已断开,下游白干活 | 超时逐层递减:Nginx 30s > 网关 25s > 服务 20s |
| 内网调用每次新建连接 | 大量 TIME_WAIT,端口耗尽 | 连接池 + keep-alive |
| 只看 HTTP 状态码判断成败 | 502 可能是 Nginx 超时而非后端逻辑错 | 分清「谁返回的错误码」 |
| TLS 证书手动一年一换 | 迟早忘记,凌晨告警 | acme.sh/Let's Encrypt 自动续期 + 过期监控 |
卡点急救
- 偶发性超时,无规律:大概率是 TCP 重传。用
ss -i看重传率,检查网络丢包(跨可用区?网卡打满?);也可能是 GC 停顿或连接池耗尽,结合应用监控区分。 - 大量 TIME_WAIT 状态:说明短连接过多。开启 keep-alive 复用;临时缓解可调内核参数
tcp_tw_reuse,但治标不治本。 - HTTPS 证书报错但浏览器能开:浏览器可能缓存了旧证书链。用
openssl s_client -connect domain:443 -servername domain看真实下发的证书,检查中间证书是否完整(缺中间证书是安卓端常见坑)。
面试常问
-
TCP 三次握手和四次挥手,为什么不能少一次? 三次握手:两次无法防止历史失效连接建立;三次才能双向确认双方的收发能力。四次挥手:因为 TCP 全双工,两边要分别关闭。服务端收到 FIN 后 ACK 先回,但自己可能还有数据没发完,所以自己的 FIN 要稍后单独发——ACK 和 FIN 不能合并(特殊情况下可合并成三次)。追问 TIME_WAIT:主动关闭方等 2MSL,确保最后一个 ACK 丢失时能重发,且让旧连接的报文在网络中消亡。
-
HTTPS 的握手过程? 简版:1) 客户端发 ClientHello(支持的 TLS 版本、加密套件、随机数 1);2) 服务端回 ServerHello + 证书 + 随机数 2;3) 客户端验证证书(CA 链、有效期、域名),生成预主密钥用服务端公钥加密发送;4) 双方用随机数 1+2+预主密钥算出会话密钥,之后对称加密通信。要点:非对称加密只用于交换会话密钥,真正传数据用对称加密(性能)。
-
输入 URL 到页面展示,中间发生了什么? 经典大题,分层答:1) DNS 解析(浏览器缓存→系统缓存→hosts→递归 DNS);2) TCP 三次握手(有 HTTPS 则 +TLS 握手);3) 发 HTTP 请求,经过 CDN(命中直接返回);4) 到 Nginx 反代,转发到后端应用;5) 应用查 Redis 缓存/DB,组装响应;6) 浏览器解析 HTML,构建 DOM/CSSOM,渲染、绘制。每一层都能展开追问,按深度准备。
自测三问
- 本站用户反馈「偶尔第一次打开慢,之后就快」,最可能是哪两层的问题?
- 为什么内网微服务之间建议用长连接?TIME_WAIT 过多的根因是什么?
- Nginx 配置了
proxy_read_timeout 30s,后端接口要处理 60 秒,会怎样?怎么改?
小结一句话
网络排查的核心是分层定位:每层有自己的协议、工具和故障特征,先定层再深挖;而超时、长连接、证书是架构师设计时必须显式决策的三件事。
延伸
- 《TCP/IP 详解 卷 1》(经典,配合 Wireshark 抓包食用)
- 《图解 HTTP》(上野宣)——入门友好
- Cloudflare Learning Center——现代网络概念图解
- 下一课:技术栈选型——Java/Spring、Go、响应式编程的权衡。