你在浏览器地址栏输入https://www.bilibili.com,按下回车,0.3秒后页面呈现。这0.3秒里,你的请求穿越了至少15个网络节点、跨越了数千公里的光纤、经过了6层协议的封装与解封、被3种不同的寻址机制接力转发。
这篇文章不讨论任何协议的细节——那是系列后续文章的任务。本文只做一件事:把这条从你家到目标网站的完整路径画出来,告诉你每一站是什么、为什么存在、如何运作。先建立全景直觉,再深入每个节点。
一、全景:从家到网站的完整路径#
1.1 一张图看全貌#
graph LR
subgraph "🏠 你的家"
A["你的PC/手机"]
A -->|"WiFi 5GHz"| B["家用路由器"]
end
subgraph "📡 接入网"
B -->|"以太网/网线"| C["光猫/ONT"]
C -->|"光纤<br/>GPON/EPON"| D["OLT<br/>运营商接入设备"]
end
subgraph "🏢 城域网 MAN"
D --> E["接入汇聚交换机"]
E --> F["BRAS/SR<br/>宽带接入服务器"]
F --> G["城域核心路由器"]
end
subgraph "🌍 骨干网"
G --> H["省干路由器"]
H --> I["国家骨干路由器"]
I --> J["IXP<br/>互联网交换中心"]
end
subgraph "🖥️ 对端网络"
J --> K["目标ISP骨干路由器"]
K --> L["目标IDC入口路由器"]
L --> M["负载均衡器/CDN"]
M --> N["Web服务器"]
end
style A fill:#87CEEB
style B fill:#87CEEB
style C fill:#DDA0DD
style D fill:#DDA0DD
style E fill:#FFD700
style F fill:#FFD700
style G fill:#FFD700
style H fill:#FFA500
style I fill:#FFA500
style J fill:#FF6B6B
style K fill:#90EE90
style L fill:#90EE90
style M fill:#90EE90
style N fill:#90EE90
这条路径可以分成五个域,每个域有不同的管理者、不同的技术、不同的物理形态:
| 域 | 范围 | 管理者 | 核心设备 | 物理形态 |
|---|
| 家居网络 | PC → 家用路由器 | 你自己 | WiFi AP、家用路由器 | 你的客厅 |
| 接入网 | 光猫 → OLT | 你的ISP | ONT、OLT、分光器 | 楼道/小区机房 |
| 城域网 | 汇聚 → 城域核心 | 你的ISP | BRAS、交换机、路由器 | 城市各处机房 |
| 骨干网 | 省干 → 国家骨干 → IXP | 骨干ISP | 大型路由器、DWDM设备 | 省际/国际光缆 |
| 对端网络 | 目标ISP → 服务器 | 目标公司/CDN | 负载均衡、服务器 | 数据中心 |
1.2 数据包的视角:一跳一跳的旅程#
互联网不是”一条线”——数据包是**一跳一跳(hop-by-hop)**转发的。每一跳只关心”下一跳往哪送”,不知道最终目的地在哪里:
graph LR
P["📦 数据包<br/>目标: www.bilibili.com"] -->|"第1跳<br/>默认网关"| R1["家用路由器<br/>192.168.1.1"]
R1 -->|"第2跳<br/>NAT转换后"| R2["BRAS<br/>10.0.0.1"]
R2 -->|"第3跳"| R3["城域核心<br/>172.16.0.1"]
R3 -->|"第4跳"| R4["省干路由器"]
R4 -->|"第5跳"| R5["国家骨干"]
R5 -->|"第6跳"| R6["IXP"]
R6 -->|"第7跳"| R7["目标ISP"]
R7 -->|"第8跳"| R8["IDC入口"]
R8 -->|"第9跳"| R9["服务器"]
style P fill:#87CEEB
每一跳的决策逻辑相同:查路由表 → 找到下一跳的IP → 发过去。就像你问路——你不知道北京怎么走,但你知道”到路口问下一个人”。
二、第一站:家居网络#
2.1 你的设备如何连上路由器#
graph TB
subgraph "你的设备"
A1["手机<br/>192.168.1.101"]
A2["笔记本<br/>192.168.1.102"]
A3["智能电视<br/>192.168.1.103"]
A4["IoT设备<br/>192.168.1.104"]
end
subgraph "家用路由器(多重身份)"
B1["WiFi AP<br/>2.4GHz/5GHz<br/>无线接入点"]
B2["以太网交换机<br/>4个LAN口<br/>有线接入"]
B3["路由器<br/>WAN口 → 接入网<br/>LAN口 → 家居网络"]
B4["DHCP服务器<br/>分配192.168.1.x<br/>私有IP地址"]
B5["NAT网关<br/>192.168.1.x ↔ 公网IP<br/>地址转换"]
B6["DNS转发器<br/>缓存DNS查询<br/>加速解析"]
end
A1 -->|"WiFi"| B1
A2 -->|"WiFi"| B1
A2 -->|"网线"| B2
A3 -->|"WiFi"| B1
A4 -->|"WiFi"| B1
B1 --> B3
B2 --> B3
B3 --> B4
B3 --> B5
B3 --> B6
B5 -->|"WAN口<br/>公网IP"| C["光猫/ONT"]
你花199元买的”家用路由器”其实是六个设备合一:
| 身份 | 做什么 | 为什么需要 |
|---|
| WiFi AP | 把有线信号变成无线电波 | 手机/笔记本没有网线口 |
| 以太网交换机 | 连接有线设备 | 台式机、电视需要稳定连接 |
| 路由器 | 在家居网络和接入网之间转发数据 | 家里是私有网络,外面是公网 |
| DHCP服务器 | 给每个设备分配私有IP地址 | 没有IP地址就无法通信 |
| NAT网关 | 把私有IP转换成公网IP | IPv4地址不够用,一个公网IP全家共享 |
| DNS转发器 | 缓存DNS查询结果 | 避免每次都去问远端DNS |
2.2 私有IP与NAT:为什么你家没有公网IP#
graph LR
subgraph "家居网络(私有地址空间)"
A["手机<br/>192.168.1.101"]
B["笔记本<br/>192.168.1.102"]
C["电视<br/>192.168.1.103"]
end
subgraph "NAT转换"
D["家用路由器<br/>公网IP: 120.36.x.x"]
end
subgraph "互联网(公网地址空间)"
E["所有公网服务"]
end
A -->|"源: 192.168.1.101:54321"| D
B -->|"源: 192.168.1.102:54322"| D
C -->|"源: 192.168.1.103:54323"| D
D -->|"源: 120.36.x.x:30001<br/>(手机请求)"| E
D -->|"源: 120.36.x.x:30002<br/>(笔记本请求)"| E
D -->|"源: 120.36.x.x:30003<br/>(电视请求)"| E
style D fill:#FFD700
关键概念:
- 私有IP地址:
192.168.x.x、10.x.x.x、172.16-31.x.x——这些地址在互联网上不可路由,只在你的家里有意义。就像公司内线电话——你拨8023能找到同事,但外面的人拨8023找不到你。
- NAT(网络地址转换):路由器把你的私有IP+端口映射成公网IP+端口。出去的时候改源地址,回来的时候改目标地址。就像公司前台——外面的人打电话到总机,前台转接到你的分机。
- 为什么需要NAT:全球IPv4地址只有约43亿个,不够每人分一个。中国IPv4地址约3.4亿个,但网民超过10亿——平均3个人共享1个公网IP。NAT让一个公网IP服务全家所有设备。
2.3 数据包离开家:第一跳#
当你的PC发送一个数据包到www.bilibili.com(假设解析后IP为116.162.x.x):
sequenceDiagram
participant PC as 你的PC
participant Router as 家用路由器
participant ONT as 光猫
PC->>PC: 1. 查路由表<br/>目标116.162.x.x不在本网段
PC->>PC: 2. 发给默认网关192.168.1.1
PC->>PC: 3. 查ARP表: 192.168.1.1的MAC地址
PC->>Router: 4. 以太网帧 → 路由器<br/>[源MAC:PC][目标MAC:路由器][IP包]
Router->>Router: 5. 收到帧,解封装看IP
Router->>Router: 6. NAT转换: 192.168.1.102:54321 → 120.36.x.x:30001
Router->>Router: 7. 查路由表: 116.162.x.x → 发往WAN口
Router->>Router: 8. 查ARP表: 下一跳的MAC地址
Router->>ONT: 9. 以太网帧 → 光猫<br/>[源MAC:路由器][目标MAC:光猫][NAT后的IP包]
这一跳发生了什么:
- 路由决策:PC发现目标IP不在本地网段,发给默认网关(家用路由器)
- ARP解析:把IP地址翻译成MAC地址(局域网内用MAC地址通信)
- NAT转换:路由器把私有IP替换成公网IP,记录映射关系
- 转发:路由器查路由表,决定从WAN口发出
三、第二站:接入网——从家到运营商#
3.1 光纤到户(FTTH)的物理拓扑#
graph TB
subgraph "🏠 你的家"
A["家用路由器"] --> B["光猫/ONT<br/>光网络终端"]
end
subgraph "🏘️ 小区"
B -->|"光纤<br/>皮线光缆"| C["分光器<br/>1:32或1:64<br/>一根光纤分给32-64户"]
C -->|"光纤"| D["分光器<br/>1:16"]
D --> E["其他住户的ONT"]
end
subgraph "🏢 小区机房/楼道"
C -->|"主干光纤"| F["OLT<br/>光线路终端<br/>运营商侧设备"]
end
subgraph "📡 运营商接入机房"
F --> G["PON口板卡"]
G --> H["OLT机框"]
H --> I["上联口 → 城域网"]
end
style B fill:#DDA0DD
style C fill:#FFD700
style F fill:#FFD700
关键概念:
- ONT(光网络终端):你家的光猫。把以太网电信号转换成光信号,通过光纤发送出去。
- OLT(光线路终端):运营商机房里的设备,对应成百上千个ONT。一个OLT的PON口通过分光器服务32-64户。
- GPON/EPON:无源光网络协议——“无源”是指分光器不需要供电,纯物理分光。一根光纤的带宽(GPON约2.5Gbps下行)被32-64户共享,但大多数时候大家不会同时满速下载,所以感知上是”独享”。
- 分光器:把一路光信号分成多路,纯物理器件,不需要供电。就像水管的三通——一根进水管分成多根出水管,水压(带宽)被分摊。
3.2 为什么你的宽带是”100M”但下载只有10MB/s#
graph LR
A["运营商承诺: 100Mbps<br/>兆比特每秒"] --> B["换算: 100 ÷ 8 = 12.5MB/s<br/>兆字节每秒"]
B --> C["实际: 约10-11MB/s<br/>协议开销+GPON共享"]
style A fill:#FFD700
style C fill:#90EE90
运营商说的”100M宽带”是100兆比特每秒(Mbps),不是100兆字节每秒(MB/s)。1字节=8比特,所以理论峰值12.5MB/s,扣除协议开销约10-11MB/s。
3.3 PPPoE:拨号的幽灵#
很多运营商仍然使用PPPoE(PPP over Ethernet)——是的,就是那个”宽带连接”拨号。虽然现在光猫自动拨号了,但PPPoE协议仍在运行:
sequenceDiagram
participant ONT as 光猫/ONT
participant BRAS as BRAS<br/>宽带接入服务器
ONT->>BRAS: 1. PPPoE发现<br/>寻找接入服务器
BRAS-->>ONT: 2. 回应: 我在这里
ONT->>BRAS: 3. PPPoE请求<br/>账号+密码
BRAS->>BRAS: 4. RADIUS认证<br/>验证账号密码
BRAS-->>ONT: 5. 分配IP地址<br/>120.36.x.x
ONT->>BRAS: 6. 开始转发数据
Note over ONT,BRAS: 每次光猫重启都会重新拨号<br/>IP地址可能变化(动态IP)
PPPoE存在的原因:运营商需要知道”谁在上网”——通过账号密码认证用户,然后分配IP地址、计费、限速。虽然技术上已经不需要”拨号”了,但PPPoE的认证和会话管理功能仍然被运营商使用。
四、第三站:城域网——运营商的城市级网络#
4.1 城域网分层拓扑#
graph TB
subgraph "接入层(离用户最近)"
A1["OLT #1<br/>小区1"]
A2["OLT #2<br/>小区2"]
A3["OLT #3<br/>小区3"]
A4["OLT #4<br/>小区4"]
end
subgraph "汇聚层(汇聚接入流量)"
B1["接入汇聚交换机 #1"]
B2["接入汇聚交换机 #2"]
end
subgraph "核心层(城域网核心)"
C1["BRAS/SR #1<br/>宽带接入服务器"]
C2["BRAS/SR #2"]
C3["城域核心路由器 #1"]
C4["城域核心路由器 #2"]
end
A1 --> B1
A2 --> B1
A3 --> B2
A4 --> B2
B1 --> C1
B1 --> C2
B2 --> C1
B2 --> C2
C1 --> C3
C2 --> C4
C3 --- C4
C3 --> D["↑ 骨干网"]
C4 --> D
style C1 fill:#FFD700
style C2 fill:#FFD700
style C3 fill:#FFA500
style C4 fill:#FFA500
城域网的三层结构:
| 层次 | 作用 | 典型设备 | 端口密度 | 覆盖范围 |
|---|
| 接入层 | 连接用户 | OLT、接入交换机 | 数百端口 | 小区/楼宇 |
| 汇聚层 | 汇聚接入层流量 | 汇聚交换机 | 数十端口 | 街道/片区 |
| 核心层 | 城域网核心交换 | BRAS、核心路由器 | 数十高速端口 | 整个城市 |
4.2 BRAS:你上网的第一道关卡#
BRAS(Broadband Remote Access Server,宽带远程接入服务器)是城域网中最重要的设备之一——它是你上网的”收费站”:
graph LR
A["你的数据包"] --> B["BRAS"]
B --> C{"认证通过?"}
C -->|"是"| D{"套餐检查"}
C -->|"否"| E["拒绝访问<br/>跳转认证页面"]
D -->|"100M套餐"| F["限速100Mbps<br/>分配IP<br/>路由到骨干网"]
D -->|"200M套餐"| G["限速200Mbps<br/>分配IP<br/>路由到骨干网"]
D -->|"欠费"| H["限速1Mbps<br/>跳转缴费页面"]
style B fill:#FFD700
BRAS做了三件事:
- 认证:验证你的PPPoE账号密码(通过RADIUS协议查询后台系统)
- 授权:根据你的套餐分配带宽、IP地址
- 计费:记录你的上网时长和流量
4.3 城域网内部的路由#
城域核心路由器之间运行OSPF或IS-IS协议——它们互相通告”我能到达哪些网络”,自动计算最短路径:
graph TB
CR1["城域核心路由器 #1<br/>负责城东"]
CR2["城域核心路由器 #2<br/>负责城西"]
CR3["城域核心路由器 #3<br/>负责城南"]
CR1 ---|"10Gbps链路"| CR2
CR2 ---|"10Gbps链路"| CR3
CR1 ---|"10Gbps链路"| CR3
CR1 -->|"上联<br/>100Gbps"| BB1["骨干网路由器 #1<br/>北京方向"]
CR2 -->|"上联<br/>100Gbps"| BB2["骨干网路由器 #2<br/>上海方向"]
style CR1 fill:#FFA500
style CR2 fill:#FFA500
style CR3 fill:#FFA500
OSPF就像城市内的导航——它知道城市内每条路的距离和拥堵情况,自动选择最快的路径。但它不知道其他城市怎么走——那是BGP的工作。
五、第四站:骨干网——跨越省份与国家#
5.1 中国互联网骨干拓扑#
graph TB
subgraph "中国电信163骨干网(简化)"
BJ["北京<br/>超级核心节点"]
SH["上海<br/>超级核心节点"]
GZ["广州<br/>超级核心节点"]
CD["成都<br/>核心节点"]
WH["武汉<br/>核心节点"]
NJ["南京<br/>核心节点"]
XA["西安<br/>核心节点"]
SY["沈阳<br/>核心节点"]
end
BJ ---|"400Gbps"| SH
BJ ---|"400Gbps"| GZ
SH ---|"400Gbps"| GZ
BJ --- CD
BJ --- SY
SH --- NJ
SH --- WH
GZ --- CD
GZ --- WH
BJ --- XA
CD --- XA
BJ -->|"国际出口<br/>海底光缆"| INT["🌍 国际互联网"]
style BJ fill:#FF6B6B
style SH fill:#FF6B6B
style GZ fill:#FF6B6B
中国互联网骨干的层级:
| 层级 | 节点 | 作用 |
|---|
| 超级核心 | 北京、上海、广州 | 全国流量调度中心,国际出口 |
| 核心节点 | 成都、武汉、南京、西安、沈阳等 | 大区流量汇聚 |
| 普通节点 | 各省会城市 | 省内流量汇聚 |
三个超级核心节点之间形成三角环——这是中国互联网骨干的骨架。所有省际流量最终都要经过这三个节点之一。
5.2 BGP:互联网的”导航系统”#
城域网内部用OSPF导航,但跨省、跨运营商的导航靠BGP(Border Gateway Protocol,边界网关协议):
graph LR
subgraph "你的ISP(中国电信)"
A["城域核心路由器"]
B["省干路由器"]
C["国家骨干路由器"]
end
subgraph "IXP(互联网交换中心)"
D["交换机<br/>连接多个ISP"]
end
subgraph "目标ISP(B站所在ISP)"
E["目标ISP骨干路由器"]
end
A --> B --> C --> D --> E
C -.->|"BGP通告:<br/>我到达116.162.0.0/16<br/>路径: 电信→IXP→目标ISP"| C
BGP的核心逻辑:
- AS(自治系统):每个运营商是一个AS,有唯一的AS号。中国电信的AS号是4134,中国联通是4837,中国移动是9808。
- BGP通告:每个AS向邻居通告”我能到达哪些IP段”。就像快递公司说”我能送到北京”。
- 路径选择:BGP选择经过AS数量最少的路径(还有其他策略,但跳数是核心因素)。就像你选快递时选中转最少的。
- 无环路:BGP路径中记录了经过的所有AS号,天然防止环路。
graph LR
A["你的ISP<br/>AS4134<br/>中国电信"] -->|"BGP路径:<br/>4134 4837"| B["中间ISP<br/>AS4837<br/>中国联通"]
B -->|"BGP路径:<br/>4134 4837 45096"| C["目标ISP<br/>AS45096<br/>B站所在网络"]
A -.->|"或者直连<br/>BGP路径: 4134 45096"| C
style A fill:#FF6B6B
style B fill:#FFD700
style C fill:#90EE90
BGP会选择路径更短的:4134 → 45096(2跳)优于 4134 → 4837 → 45096(3跳)。
5.3 IXP:互联网的”交通枢纽”#
IXP(Internet Exchange Point,互联网交换中心)是多个ISP互联的物理场所:
graph TB
subgraph "IXP(如: 国家交换中心)"
SW["核心交换机<br/>超大容量"]
end
subgraph "参与方"
CT["中国电信<br/>AS4134"]
CU["中国联通<br/>AS4837"]
CM["中国移动<br/>AS9808"]
CDN["阿里云CDN<br/>AS37963"]
INT["国际ISP<br/>AS174"]
EDU["中国教育和科研计算机网<br/>AS4538"]
end
CT ---|"BGP Peering<br/>10Gbps+"| SW
CU ---|"BGP Peering"| SW
CM ---|"BGP Peering"| SW
CDN ---|"BGP Peering"| SW
INT ---|"BGP Peering"| SW
EDU ---|"BGP Peering"| SW
style SW fill:#FF6B6B
IXP为什么重要:
没有IXP时,电信用户访问联通服务器上的网站,数据要绕道骨干网到北京/上海/广州的直连点再绕回来——可能多走数千公里。有了IXP,电信和联通在本地直接交换流量,延迟大幅降低。
中国主要的IXP包括:中国互联网交换中心(北京、上海、广州)、国家交换中心等。
5.4 海底光缆:连接世界的血管#
graph TB
subgraph "亚太地区主要海底光缆"
A["APG<br/>亚太门户光缆<br/>中国-日本-东南亚"]
B["SEA-ME-WE 5<br/>东南亚-中东-西欧"]
C["NCP<br/>新跨太平洋光缆<br/>中国-美国"]
D["TPE<br/>跨太平洋表达光缆<br/>中国-美国"]
E["SJC<br/>东南亚-日本光缆"]
end
subgraph "登陆站"
LS_QD["青岛登陆站"]
LS_SH["上海崇明登陆站"]
LS_SZ["汕头登陆站"]
end
C --> LS_QD
D --> LS_SH
A --> LS_SH
B --> LS_SZ
E --> LS_SZ
style C fill:#FF6B6B
style D fill:#FF6B6B
关键数据:
- 一条跨太平洋海底光缆长度约15,000-20,000公里
- 光信号在光纤中传播速度约200,000公里/秒(光速的2/3,因为光纤折射率约1.5)
- 中国到美国单程延迟约70-80ms(光速物理极限约50ms + 设备处理延迟)
- 一条现代海底光缆容量可达数十Tbps
六、协议栈解剖:数据包的六层封装#
6.1 从应用层到物理层:层层包装#
当你访问https://www.bilibili.com时,你的HTTP请求经历了六层封装——每一层加上自己的头部,就像俄罗斯套娃:
graph TB
subgraph "📦 发送端:层层封装"
A["应用层: HTTP GET /<br/>原始请求"]
B["表示层: TLS加密<br/>+ TLS头"]
C["传输层: TCP段<br/>+ TCP头(端口号80/443)"]
D["网络层: IP包<br/>+ IP头(源IP/目标IP)"]
E["数据链路层: 以太网帧<br/>+ 帧头(MAC地址)+ 帧尾(CRC校验)"]
F["物理层: 电信号/光信号<br/>0101001110..."]
end
A --> B --> C --> D --> E --> F
subgraph "📬 接收端:层层解封"
A2["应用层: HTTP GET /<br/>还原请求"]
B2["表示层: TLS解密"]
C2["传输层: 重组TCP段"]
D2["网络层: 路由转发"]
E2["数据链路层: 帧校验"]
F2["物理层: 信号解码"]
end
F2 --> E2 --> D2 --> C2 --> B2 --> A2
6.2 每一层的真实数据#
以一个HTTP请求为例,看看每一层到底加了什么:
graph TB
subgraph "一个HTTP请求的完整封装"
direction TB
L2["以太网帧头<br/>━━━━━━━━━━━━━━<br/>目标MAC: 00:11:22:33:44:55<br/>源MAC: AA:BB:CC:DD:EE:FF<br/>类型: 0x0800 (IPv4)<br/>━━━━━━━━━━━━━━<br/>14字节"]
L3["IP头<br/>━━━━━━━━━━━━━━<br/>版本: IPv4<br/>源IP: 192.168.1.102 (NAT后120.36.x.x)<br/>目标IP: 116.162.x.x<br/>TTL: 64 (每经一跳减1)<br/>协议: TCP (6)<br/>━━━━━━━━━━━━━━<br/>20字节"]
L4["TCP头<br/>━━━━━━━━━━━━━━<br/>源端口: 54321 (随机)<br/>目标端口: 443 (HTTPS)<br/>序列号: 用于可靠传输<br/>确认号: 用于可靠传输<br/>标志位: SYN/ACK/PSH/FIN<br/>━━━━━━━━━━━━━━<br/>20字节"]
L5["TLS头<br/>━━━━━━━━━━━━━━<br/>版本: TLS 1.3<br/>内容类型: Application Data<br/>加密后的HTTP请求<br/>━━━━━━━━━━━━━━<br/>5字节+加密数据"]
L6["HTTP请求(加密前)<br/>━━━━━━━━━━━━━━<br/>GET / HTTP/1.1<br/>Host: www.bilibili.com<br/>User-Agent: Mozilla/5.0...<br/>Accept: text/html<br/>━━━━━━━━━━━━━━"]
L7["以太网帧尾<br/>━━━━━━━━━━━━━━<br/>FCS: CRC32校验<br/>━━━━━━━━━━━━━━<br/>4字节"]
end
L2 --> L3 --> L4 --> L5 --> L6
L5 --> L7
style L2 fill:#DDA0DD
style L3 fill:#87CEEB
style L4 fill:#90EE90
style L5 fill:#FFD700
style L6 fill:#FFA500
style L7 fill:#DDA0DD
6.3 每一层的关键问题#
| 层次 | 关键问题 | 解决机制 | 对应设备 |
|---|
| 物理层 | 0和1如何在介质上传输? | 电平编码/光调制 | 光纤、网线、WiFi |
| 数据链路层 | 同一链路上的设备如何互相识别? | MAC地址 | 交换机 |
| 网络层 | 不同链路之间如何转发? | IP地址 + 路由表 | 路由器 |
| 传输层 | 数据如何可靠到达? | TCP序列号/确认号 | 端系统(你的PC和服务器) |
| 表示层 | 数据如何保密? | TLS加密 | 端系统 |
| 应用层 | 用户想要什么? | HTTP请求/响应 | 浏览器和Web服务器 |
重要认知:交换机只看MAC地址(数据链路层),路由器只看IP地址(网络层),中间的设备看不到TCP、TLS、HTTP——它们只关心”下一跳往哪送”。
七、DNS:互联网的”电话簿”#
7.1 DNS解析的完整过程#
在数据包出发之前,你的PC需要知道www.bilibili.com的IP地址——这就是DNS解析:
sequenceDiagram
participant PC as 你的PC
participant Router as 家用路由器<br/>DNS转发器
participant Local as 运营商本地DNS<br/>120.36.0.1
participant Root as 根DNS服务器
participant TLD as .com TLD服务器
participant Auth as bilibili.com<br/>权威DNS服务器
PC->>Router: 1. www.bilibili.com的IP是多少?
Router->>Local: 2. 缓存未命中,转发查询
Local->>Local: 3. 检查缓存,未命中
Local->>Root: 4. .com的DNS服务器在哪?
Root-->>Local: 5. .com TLD服务器列表
Local->>TLD: 6. bilibili.com的DNS服务器在哪?
TLD-->>Local: 7. ns1.bilibili.com的IP
Local->>Auth: 8. www.bilibili.com的IP是多少?
Auth-->>Local: 9. 116.162.x.x (CNAME → CDN IP)
Local-->>Router: 10. 116.162.x.x
Router-->>PC: 11. 116.162.x.x
Router->>Router: 12. 缓存结果<br/>TTL=300秒
DNS的层级结构:
| 层级 | 作用 | 数量 | 示例 |
|---|
| 根DNS | 知道所有TLD服务器的位置 | 全球13组(任播) | a.root-servers.net |
| TLD DNS | 知道该顶级域下所有域名的权威DNS | 数百个 | .com、.cn、.org |
| 权威DNS | 知道该域名下所有记录的IP | 每个域名自建或托管 | ns1.bilibili.com |
| 本地DNS | 替用户完成递归查询并缓存 | 每个ISP部署 | 120.36.0.1 |
为什么需要这么多层?因为全球有数亿个域名,没有任何一台DNS服务器能存储所有记录。分层让每层只负责一小部分——根DNS只需要知道”.com服务器在哪”,不需要知道”bilibili.com的IP是多少”。
7.2 CDN如何改变DNS解析#
B站不会直接告诉你服务器的真实IP——它通过CNAME指向CDN,CDN返回离你最近的节点IP:
sequenceDiagram
participant PC as 你的PC
participant DNS as 本地DNS
participant Auth as bilibili权威DNS
participant CDN_DNS as CDN智能DNS
PC->>DNS: www.bilibili.com?
DNS->>Auth: 查询
Auth-->>DNS: CNAME: www.bilibili.com.cdn20.com<br/>(不是IP,是CDN域名)
DNS->>CDN_DNS: www.bilibili.com.cdn20.com?
CDN_DNS->>CDN_DNS: 根据请求来源IP判断<br/>你在北京电信<br/>返回北京电信节点的IP
CDN_DNS-->>DNS: 116.162.x.x(北京CDN节点)
DNS-->>PC: 116.162.x.x
CDN智能DNS的关键:它根据你的本地DNS的IP地址(而不是你的IP)判断你的位置。这就是为什么你改了DNS为8.8.8.8后,访问某些网站可能变慢——因为Google的8.8.8.8任播节点可能不在你附近,CDN误判了你的位置。
八、TCP连接:三次握手与慢启动#
8.1 TCP三次握手#
在发送HTTP请求之前,你的PC和服务器需要先建立TCP连接:
sequenceDiagram
participant PC as 你的PC<br/>116.162.x.x:54321
participant Server as 服务器<br/>116.162.x.x:443
Note over PC,Server: 第1次握手: SYN
PC->>Server: SYN<br/>序列号=1000<br/>"我想建立连接"
Note over PC,Server: 第2次握手: SYN+ACK
Server-->>PC: SYN+ACK<br/>序列号=2000, 确认号=1001<br/>"同意,我也想建立连接"
Note over PC,Server: 第3次握手: ACK
PC->>Server: ACK<br/>序列号=1001, 确认号=2001<br/>"确认,连接建立"
Note over PC,Server: 连接建立,开始TLS握手
为什么是三次?两次不够——因为服务器需要确认客户端收到了自己的SYN+ACK。如果只有两次,服务器无法确认客户端是否真的在监听——可能是一个伪造的源地址(SYN Flood攻击)。
8.2 TCP慢启动:为什么第一个请求总是慢#
TCP连接建立后不会立即全速发送——它从很小的窗口开始,逐步增加:
graph LR
subgraph "慢启动过程"
A["RTT 1<br/>发送1个包<br/>~1.4KB"] --> B["RTT 2<br/>发送2个包<br/>~2.8KB"]
B --> C["RTT 3<br/>发送4个包<br/>~5.6KB"]
C --> D["RTT 4<br/>发送8个包<br/>~11.2KB"]
D --> E["RTT 5<br/>发送16个包<br/>~22.4KB"]
E --> F["...指数增长..."]
F --> G["达到带宽上限<br/>进入拥塞避免<br/>线性增长"]
end
这就是为什么HTTP/2和HTTP/3很重要——它们在一个TCP连接上复用多个请求,避免了每次新请求都要经历慢启动。HTTP/3甚至用QUIC(基于UDP)替代TCP,连接建立和加密握手合并为1-RTT。
九、TLS:加密通道的建立#
9.1 TLS 1.3握手#
在TCP连接建立后,浏览器和服务器还要建立加密通道:
sequenceDiagram
participant PC as 你的PC
participant Server as 服务器
Note over PC,Server: TCP三次握手完成
PC->>Server: ClientHello<br/>TLS 1.3<br/>支持的加密套件<br/>Key Share (DH公钥)
Server-->>PC: ServerHello<br/>选定加密套件<br/>Key Share (DH公钥)<br/>Certificate (服务器证书)<br/>CertificateVerify (签名)<br/>Finished
PC->>PC: 验证证书链<br/>确认服务器身份
PC->>Server: Finished<br/>加密通信开始
Note over PC,Server: TLS 1.3: 1-RTT握手<br/>TLS 1.2: 2-RTT握手
TLS 1.3的关键改进:
- 1-RTT握手:从2-RTT减少到1-RTT,节省一个往返
- 0-RTT恢复:如果之前连接过,可以0-RTT恢复加密通信
- 更安全的加密:移除了不安全的加密算法,只保留AEAD加密
9.2 证书链:你如何信任服务器#
graph TB
A["根CA<br/>DigiCert Global Root CA<br/>预装在浏览器/操作系统中"] --> B["中间CA<br/>DigiCert SHA2 Secure Server CA"]
B --> C["终端证书<br/>www.bilibili.com<br/>公钥 + 签名"]
A -->|"浏览器内置信任"| D["✅ 信任根CA"]
D -->|"根CA签名验证"| E["✅ 信任中间CA"]
E -->|"中间CA签名验证"| F["✅ 信任www.bilibili.com"]
style A fill:#90EE90
style B fill:#FFD700
style C fill:#87CEEB
你的浏览器信任www.bilibili.com,不是因为你知道这个网站,而是因为:
- 浏览器内置信任根CA(如DigiCert)
- 根CA签发了中间CA的证书(签名可验证)
- 中间CA签发了
www.bilibili.com的证书(签名可验证)
- 证书中的域名与你要访问的域名匹配
十、CDN:为什么你访问的往往不是源站#
10.1 CDN的物理拓扑#
graph TB
subgraph "用户侧"
U1["北京用户"]
U2["上海用户"]
U3["广州用户"]
U4["成都用户"]
end
subgraph "CDN边缘节点(PoP)"
P1["北京PoP<br/>电信+联通"]
P2["上海PoP<br/>电信+联通"]
P3["广州PoP<br/>电信+联通"]
P4["成都PoP<br/>电信"]
end
subgraph "CDN中间层"
M1["区域汇聚<br/>华北"]
M2["区域汇聚<br/>华东"]
M3["区域汇聚<br/>华南"]
end
subgraph "源站"
O["B站源站<br/>上海IDC"]
end
U1 --> P1
U2 --> P2
U3 --> P3
U4 --> P4
P1 --> M1
P2 --> M2
P3 --> M3
P4 --> M1
M1 --> O
M2 --> O
M3 --> O
P1 -.->|"缓存命中<br/>直接返回"| U1
P1 -.->|"缓存未命中<br/>回源获取"| M1
style O fill:#FF6B6B
style P1 fill:#90EE90
style P2 fill:#90EE90
style P3 fill:#90EE90
style P4 fill:#90EE90
CDN的核心逻辑:
- DNS调度:把用户引导到最近的PoP节点
- 缓存:PoP节点缓存热门内容,直接返回,不需要回源
- 回源:缓存未命中时,PoP向源站请求内容,然后缓存并返回给用户
10.2 有CDN vs 无CDN的路径对比#
graph LR
subgraph "无CDN: 所有请求直达源站"
A1["北京用户"] -->|"~30ms<br/>城域网"| B1["北京骨干"]
B1 -->|"~15ms<br/>骨干网"| C1["上海骨干"]
C1 -->|"~5ms<br/>城域网"| D1["上海源站"]
Note1["总延迟: ~50ms<br/>每条请求都走完整路径"]
end
subgraph "有CDN: 请求到最近的PoP"
A2["北京用户"] -->|"~5ms<br/>城域网"| B2["北京PoP<br/>缓存命中"]
Note2["总延迟: ~5ms<br/>90%+请求在边缘命中"]
end
style D1 fill:#FF6B6B
style B2 fill:#90EE90
CDN的效果:
- 延迟降低:从50ms降到5ms(10倍改善)
- 带宽节省:90%+请求在边缘命中,源站带宽需求降低10倍
- 可用性提升:即使源站故障,边缘缓存仍可服务
十一、数据中心:请求到达终点#
11.1 数据中心内部拓扑#
graph TB
subgraph "数据中心内部"
direction TB
A["边界路由器<br/>连接ISP/IXP"]
B["核心交换机<br/>Spine层"]
C1["Leaf交换机 #1"]
C2["Leaf交换机 #2"]
C3["Leaf交换机 #3"]
D1["负载均衡器<br/>F5/Nginx/Envoy"]
D2["负载均衡器"]
E1["Web服务器集群<br/>K8s Pod"]
E2["API服务器集群"]
E3["缓存集群<br/>Redis/Memcached"]
F1["数据库集群<br/>MySQL/TiDB"]
F2["对象存储<br/>S3/MinIO"]
end
A --> B
B --> C1
B --> C2
B --> C3
C1 --> D1
C2 --> D1
C2 --> D2
C3 --> D2
D1 --> E1
D1 --> E2
D2 --> E2
D2 --> E3
E2 --> F1
E2 --> F3
E3 --> F1
style A fill:#FF6B6B
style B fill:#FFA500
style D1 fill:#FFD700
style E1 fill:#90EE90
Spine-Leaf架构:现代数据中心使用Spine-Leaf(脊叶)架构替代传统三层架构——任何两台服务器之间恰好经过Spine和Leaf两跳,延迟可预测。
11.2 负载均衡:一台服务器扛不住#
graph LR
A["用户请求<br/>116.162.x.x:443"] --> B["负载均衡器<br/>VIP: 116.162.x.x"]
B --> C{"调度策略"}
C -->|"轮询"| D1["Web服务器 #1<br/>10.0.1.1:8080"]
C -->|"最少连接"| D2["Web服务器 #2<br/>10.0.1.2:8080"]
C -->|"IP Hash"| D3["Web服务器 #3<br/>10.0.1.3:8080"]
style B fill:#FFD700
负载均衡器是数据中心的”前台”——它持有公网IP(VIP),接收所有请求,然后分发给后端的真实服务器。用户只看到VIP,不知道后面有多少台服务器。
十二、完整旅程回顾#
12.1 一个HTTP请求的完整时间线#
graph LR
subgraph "0-1ms: 家居网络"
A1["DNS缓存查询"]
A2["ARP解析"]
A3["WiFi传输"]
end
subgraph "1-5ms: 接入网"
B1["GPON上行"]
B2["OLT处理"]
end
subgraph "5-10ms: 城域网"
C1["BRAS认证+路由"]
C2["城域核心转发"]
end
subgraph "10-20ms: 骨干网"
D1["省干路由"]
D2["IXP交换"]
end
subgraph "20-25ms: 对端网络"
E1["目标ISP路由"]
E2["CDN边缘命中"]
end
subgraph "25-30ms: TLS+HTTP"
F1["TCP握手: 1-RTT"]
F2["TLS握手: 1-RTT"]
F3["HTTP请求+响应"]
end
12.2 延迟分解#
| 阶段 | 典型延迟 | 占比 | 说明 |
|---|
| DNS解析 | 1-50ms | 变化大 | 缓存命中1ms,未命中可能50ms+ |
| TCP握手 | 1-RTT | 固定 | 一个往返延迟 |
| TLS握手 | 1-RTT | 固定 | TLS 1.3,首次2-RTT |
| HTTP请求+响应 | 1-RTT | 固定 | 请求发送+响应返回 |
| 网络传输 | 5-80ms | 变化大 | 取决于距离和路径 |
对于北京用户访问北京CDN节点:总延迟约25-30ms(DNS缓存 + 1-RTT TCP + 1-RTT TLS + 1-RTT HTTP + 网络传输)
对于北京用户访问美国源站:总延迟约300-500ms(跨太平洋光缆约80ms/RTT,3-4个RTT)
12.3 全景回顾图#
graph TB
subgraph "🏠 你家"
A["PC/手机"] --> B["家用路由器<br/>NAT/DHCP/DNS转发"]
end
subgraph "📡 接入网"
B --> C["光猫ONT"] --> D["分光器"] --> E["OLT"]
end
subgraph "🏢 城域网"
E --> F["汇聚交换机"] --> G["BRAS<br/>认证/授权/计费"]
G --> H["城域核心路由器<br/>OSPF路由"]
end
subgraph "🌍 骨干网"
H --> I["省干路由器"]
I --> J["国家骨干路由器<br/>BGP路由"]
J --> K["IXP<br/>多ISP互联"]
end
subgraph "🖥️ 对端"
K --> L["目标ISP骨干"]
L --> M["CDN边缘PoP<br/>缓存命中?"]
M -->|"命中"| N["直接返回<br/>✅ 最快"]
M -->|"未命中"| O["回源站<br/>⬇️ 较慢"]
O --> P["数据中心<br/>Spine-Leaf"]
P --> Q["负载均衡器"]
Q --> R["Web服务器"]
end
style A fill:#87CEEB
style G fill:#FFD700
style J fill:#FFA500
style K fill:#FF6B6B
style M fill:#90EE90
style R fill:#90EE90
十三、我的思考#
13.1 互联网是”没有全局地图”的导航系统#
互联网最反直觉的地方在于:没有任何一个节点拥有全局路由信息。你的家用路由器只知道”默认网关”,城域路由器只知道”省干方向”,骨干路由器只知道”下一个AS”。每个节点只关心下一跳,没有人知道完整路径。
这就像你问路——你问”北京怎么走”,路人说”往前走到高速入口”,高速入口说”走G2”,G2上的路牌说”前方北京”。没有人需要知道从你家到北京的完整路线,每个人只需要知道”下一步往哪走”。
这种设计是互联网可扩展性的基础——如果每个路由器都要知道全球所有路径,路由表会大到无法处理。
13.2 延迟的物理极限无法突破#
光在光纤中的传播速度约200,000公里/秒。中国到美国的直线距离约11,000公里,光纤路径约15,000-20,000公里。单程延迟的物理极限约75-100ms,一个RTT约150-200ms。
这意味着,无论技术如何进步,中国用户访问美国服务器的延迟不可能低于150ms。物理定律决定了互联网延迟的下限。CDN、边缘计算、本地缓存——所有这些技术的本质都是”把数据搬到离用户更近的地方”,因为搬数据的速度永远比光速快不了。
13.3 NAT是权宜之计,IPv6是未来#
NAT让全球10亿中国网民共享3.4亿个IPv4地址——这是IPv4地址耗尽下的权宜之计。但NAT破坏了互联网的端到端原则:你的手机没有公网IP,外面的人无法主动连接你。这意味着P2P通信、远程访问、WebRTC视频通话都需要NAT穿透技术(STUN/TURN),增加了复杂性和延迟。
IPv6为每个设备分配公网地址(2^128个地址,足够给地球上每粒沙子分配一个),恢复端到端通信。中国IPv6部署率已超过70%,但很多应用仍然优先使用IPv4——因为IPv4”能用”,而迁移需要成本。
13.4 互联网的脆弱性#
这条从家到网站的路径上,任何一个节点的故障都会影响你的上网体验:
- 光缆被挖断:施工挖断光缆,整个小区断网(每年发生数千次)
- BGP路由劫持:某个AS错误地通告了不属于自己的IP段,流量被错误路由(2008年巴基斯坦YouTube事件)
- DNS污染:DNS查询被篡改,返回错误的IP地址
- IXP故障:交换中心故障,多个ISP之间无法互联
- CDN故障:2023年Cloudflare故障导致全球数千网站不可访问
互联网的鲁棒性来自冗余——多条路径、多个DNS服务器、多个CDN节点。但冗余不是无限的,关键节点的故障仍然可能导致大范围中断。
十四、总结#
从你家到目标网站的路径,穿越了五个域:家居网络、接入网、城域网、骨干网、对端网络。每一站都有不同的管理者、不同的技术、不同的物理形态,但它们通过统一的协议(以太网、IP、TCP、TLS、HTTP)协同工作,让数据包能够一跳一跳地从你的浏览器到达目标服务器。
这条路径上的关键概念:
- NAT:让一个公网IP服务全家所有设备——IPv4地址耗尽的权宜之计
- GPON:一根光纤通过分光器服务32-64户——带宽共享但感知独享
- BRAS:运营商的收费站——认证、授权、计费、限速
- OSPF:城域网内的导航——知道城市内每条路的距离
- BGP:跨运营商的导航——知道到达每个AS的路径
- IXP:互联网的交通枢纽——让ISP在本地直接交换流量
- DNS:互联网的电话簿——域名到IP的翻译,CDN调度的入口
- CDN:把内容搬到离用户最近的地方——延迟降低10倍
- TCP慢启动:从1个包开始指数增长——为什么新连接总是慢
- TLS:加密通道——即使中间人截获数据也无法解密
系列后续文章将逐一深入每个节点的技术细节。本文建立的全景直觉,是理解后续内容的地图。