CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
软件架构师入门/课时/网络基础
RawBlame
课时目录12 节

软件架构师入门

  1. 01软件架构是什么
  2. 02架构师软技能
  3. 03设计模式与原则
  4. 04架构风格
  5. 05数据架构
  6. 06API 与集成
  7. 07安全架构
  8. 08云与设计模式
  9. 09网络基础
  10. 10技术栈选型
  11. 11治理与方法论
  12. 12综合练习

网络基础

OSI、HTTP/TLS 与代理。

25 分钟

网络基础

这一课你将能做到

  1. 画出一次 HTTPS 请求的完整链路:DNS → TCP 三次握手 → TLS 握手 → HTTP 请求 → 响应
  2. 用 curl、ping、telnet、dig 四个命令定位「网站打不开」的故障层
  3. 配置本站的 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;
    }
}

讲清楚要点

  1. 分层思维是排查的第一原则:先确定故障在哪一层,再深入。DNS 不通查 IP 没意义,TCP 不通发 HTTP 请求没意义。每层的排查工具不同:dig(DNS)、ping/traceroute(网络层)、telnet/ss(传输层)、curl(应用层)。
  2. TCP 的可靠性是有代价的:三次握手(1 个 RTT)+ 慢启动,短连接场景开销巨大。所以 HTTP/1.1 有 keep-alive 复用连接,HTTP/2 多路复用,HTTP/3 干脆换 QUIC(UDP 之上自建可靠性)。
  3. TLS 保护三样东西:机密性(内容加密)、完整性(防篡改)、身份认证(证书证明你确实是 coderoadmap.cn)。证书过期是线上高频事故,必须监控自动续期。
  4. 反向代理 vs 正向代理:正向代理站在客户端这边(科学上网工具);反向代理站在服务端这边(Nginx),客户端不知道后端真实地址。负载均衡、TLS 终止、静态资源、缓存都是反向代理的职责。
  5. 超时是网络编程的头等大事:不设超时的请求会在线程池耗尽后拖垮整个服务。原则:每一层都要有超时,且下游超时 < 上游超时(否则上游已放弃,下游还在干)。

你可能会懵的地方

  • 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 自动续期 + 过期监控

卡点急救

  1. 偶发性超时,无规律:大概率是 TCP 重传。用 ss -i 看重传率,检查网络丢包(跨可用区?网卡打满?);也可能是 GC 停顿或连接池耗尽,结合应用监控区分。
  2. 大量 TIME_WAIT 状态:说明短连接过多。开启 keep-alive 复用;临时缓解可调内核参数 tcp_tw_reuse,但治标不治本。
  3. 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,渲染、绘制。每一层都能展开追问,按深度准备。

自测三问

  1. 本站用户反馈「偶尔第一次打开慢,之后就快」,最可能是哪两层的问题?
  2. 为什么内网微服务之间建议用长连接?TIME_WAIT 过多的根因是什么?
  3. Nginx 配置了 proxy_read_timeout 30s,后端接口要处理 60 秒,会怎样?怎么改?

小结一句话

网络排查的核心是分层定位:每层有自己的协议、工具和故障特征,先定层再深挖;而超时、长连接、证书是架构师设计时必须显式决策的三件事。

延伸

  • 《TCP/IP 详解 卷 1》(经典,配合 Wireshark 抓包食用)
  • 《图解 HTTP》(上野宣)——入门友好
  • Cloudflare Learning Center——现代网络概念图解
  • 下一课:技术栈选型——Java/Spring、Go、响应式编程的权衡。
加载本节练习…
← 上一课云与设计模式下一课 →技术栈选型