如果你正打算认真啃一遍计算机网络基础,我的建议是别一头扎进教科书里背七层模型,而是沿着一条实际问题链条走下来:一个数据包从网卡出发,如何靠 MAC 找到直连设备,如何靠 IP 跨网寻路,如何靠 DNS 把域名翻译成机器认识的地址,最后又是如何靠 CDN 把内容搬到离你最近的地方。这条从 MAC、IP 到 DNS 与 CDN 的链路,是我这些年排查故障、带新人入门时用的核心框架,也是网络第一课里最值得先吃透的主线。
这篇文章就是围绕这条主线展开的学习笔记,除了把原理讲清楚,还会带上可直接上手的抓包命令、排查步骤和那些教材里通常不会写的坑。适合刚开始学网络基础的同学,也适合日常工作需要跟网络打交道的应用开发、运维和全栈工程师,哪怕你只是想知道“为什么我改了 DNS 却不生效”或“首页为什么时快时慢”,读完也能找到答案。
1. 为什么网络基础要从这条主线学起
1.1 三个地址各管一摊事,别混在一起
先厘清一个最常见的误区:很多人把 MAC 和 IP 当成黑白双煞,总觉得两个地址是不是有一个冗余。其实它们分别对应不同层面的身份标识:MAC 是设备出厂时烧录在网卡上的身份编号,你可以理解成身份证号,一辈子基本不变;IP 是设备当前身处网络的“门牌号”,可以搬家、可以改租,只要在一个网络里就有效。身份证号不能让快递员找到你,门牌号才能。
MAC 属于数据链路层的概念,负责解决“同一段物理链路上,下一跳到底是谁”;IP 属于网络层的概念,负责解决“目标地址在哪一个网络”。数据包出门时,脑子里想的永远是目标 IP,但真正到发送动作,每一跳都要靠 MAC 来完成“接力棒交接”。DNS 和 CDN 则在这个链条的侧面:DNS 负责把人类输入的域名翻译成 IP,CDN 负责把这个 IP“偷梁换柱”成离你最近的缓存节点地址。
把这几个角色串起来,看一个最简单的情景:你在浏览器里输入某个域名并回车,浏览器先问 DNS“这个域名对应的 IP 是多少”;拿到 IP 后,发起 TCP 连接;数据包到达路由器时,路由器通过 ARP 协议找到下一跳设备的 MAC 地址;经过层层转发后,目标服务器收到请求并返回内容。如果目标域名接入了 CDN,那么 DNS 返回的其实不是源站 IP,而是 CDN 调度的边缘节点 IP,后续请求就被引导到了那个节点。
1.2 概念直接对应日常故障
这套框架不是用来应付考试的,它和日常问题严重绑定。
如果你看到手机上显示“已连接但没有网络”,多半是 DHCP 没有从路由器拿到合法 IP,系统自动分配了一个 169.254.x.x 的链路本地地址,这个地址只能和同一网段内的人通信,出不了门。
如果你打开某个网页,浏览器报DNS_PROBE_FINISHED_NXDOMAIN,说明域名压根没解析出来,本地 DNS 里没有记录,上游递归解析器也没找到,可能是注册商那边解析记录已经掉了,或者你本地 hosts 文件写错了奇怪指向。
如果你发现网页里的图片加载特别慢,但视频站点秒开,那可能是源站带宽问题,也可能是 CDN 没有命中缓存,边缘节点替你回了一次源,又恰逢源站链路抖动。
同样一套网络基础逻辑,既能解释“连不上”,也能解释“慢”,这也是为什么我建议第一课就沿着 MAC、IP、DNS、CDN 这条线去学。你每学一个概念,手边就多一把排查工具,而不是学完满脑子概念却无处安放。
1.3 这条线还满足了不同学习目标
对新手来说,这条线覆盖了从底层到应用层最核心的寻址与调度机制,是后续学习 TCP、HTTP、容器网络、云网络的地基;对应用开发者来说,DNS 缓存问题、IP 冲突问题、CDN 刷新问题几乎避不开;对运维和网络工程师来说,ARP 表、DNS 记录、CDN 调度是最常见的操作对象。可以说,无论你往哪个方向深入,这几个概念都是必经之路。
2. MAC 与 IP:网卡的身份和网络的地址
2.1 MAC 地址是烧录的,但也能改
MAC 地址一共 48 位,通常写成十六进制六组,例如00:1a:2b:3c:4d:5e。前 24 位是厂商代码,全称 OUI,由 IEEE 分配给各网卡厂商;后 24 位是厂商内部自行分配的序列号。理论上一张网卡在全球范围内是唯一的。但注意,这是理论。实际中,你完全可以在系统层面改掉它,因为很多网卡驱动允许上层接口覆盖 MAC。
你可以在自己的电脑上验证这个特点:
# Linux 查看当前网卡 MAC ip addr show eth0 # Linux 临时修改 MAC sudo ip link set eth0 address 00:1a:2b:3c:4d:5e sudo ip link set eth0 upWindows 下用getmac命令查看,修改则在“网络适配器属性 -> 高级 -> 网络地址”里填一个 12 位十六进制字符串。改 MAC 有什么用?最常见的场景是校园网或酒店认证系统绑定了设备 MAC,换机器后如果不想找管理员解绑,直接把新机器的网卡 MAC 改成旧值就能绕过。另外做虚拟机克隆时,如果不改 MAC,两台一模一样的机器同时出现在一个局域网里,交换机 MAC 表会跳来跳去,网络就会时不时抽风。
提到交换机 MAC 表,这是 IT 人员必须理解的机制:交换机不识别 IP,它只根据帧里的目的 MAC 查询自己的转发表,找到对应端口后把帧从那个端口转发出去。转发表就是通过源源不断的源 MAC 学习出来的。新手在看协议栈时容易忽略这一层,但实际上,在绝大多数交换机上跑抓包,你看到的核心内容就是 MAC 地址的不断更新和转发。
2.2 IP 地址的网络号和主机号:子网掩码到底在分割什么
IP 地址实际分为两个部分:网络号用于定位“你属于哪个网络”,主机号用于定位“网络里的哪台设备”。子网掩码的作用就是划分这个边界。
拿最常见的192.168.1.0/24来说,/24表示前 24 位是网络号,后 8 位是主机号,所以这个网段一共有 2 的 8 次方个地址,其中第一个是网络地址本身,最后一个是广播地址,实际可分配给设备的是 254 个。看到这里,你应该能回答一个面试高频问题:/24网段里最多有多少台可用主机?答案是 254,不是 256。
公网地址和私网地址的区分也要记牢。三个私网段分别是10.0.0.0/8、172.16.0.0/12、192.168.0.0/16。你的路由器和家庭设备分配的 IP 基本都在这些段内。私网地址不能在互联网上直接路由,家里的设备要上网,必须靠路由器做 NAT,将内网 IP 映射成公网 IP 之后才能出去。这就是为什么你能同时刷手机和笔记本,但运营商那边只看到家里路由器一个公网 IP。
2.3 跨网段通信:对方 MAC 为什么是网关的 MAC
这是整个网络基础里最重要的一个思维方式转变。
同一网段内通信很简单:发送方看目标 IP 和自己在同一子网,直接发 ARP 询问“谁知道这个 IP 对应的 MAC”,拿到应答后就封装帧发出去。
跨网段通信就绕了一个弯:发送方一看目标 IP 不在同一子网,它会先把数据包发给默认网关,此时 ARP 查询的目标是网关 IP 对应的 MAC,而不是目标服务器。数据包到了网关之后,由网关再路由到下一个网络,重新封装新帧。换句话说,数据包里的源 IP 和目标 IP 自始至终不变,但每一跳的源 MAC 和目标 MAC 都在更新。
这就是为什么很多第一次抓包的人,明明访问的是一个远程服务器,抓包看到的目的 MAC 却是自己家路由器的 MAC,然后误以为网卡坏掉或者抓包工具出了问题。这不是问题,是正常机制。
可以动手验证一下 ARP 缓存:
# 查看本机 ARP 缓存表 arp -a # 清空缓存后再观察一次 sudo ip neigh flush all ping 192.168.1.1执行ping前后各看一次arp -a,你会发现新的表项冒了出来,这比背概念深刻得多。
2.4 实操:抓一次 ARP 解析过程
抓 ARP 包不需要特别复杂的环境,虚拟机里两台机器互 ping 即可。以 Linux 为例,在一台机器上开启抓包:
sudo tcpdump -i eth0 -e -nn arp另一台机器执行ping目标地址,随后抓包输出里能看到典型的“谁知道 IP X 的 MAC 地址?请告诉 Y”以及“X 的 MAC 是 xx:xx:xx:xx:xx:xx”。第一句是广播请求,目标 MAC 是全f,第二句是单播应答。两条消息加在一起,就是 ARP 协议的全部核心内容:请求广播、应答单播。
这个实验建议每个初学者都做一次,因为抓完之后你会非常直观地理解“MAC 用于本地链路寻址”这句话的含义。ARP 请求不可能跨越路由器,你的局域网里多少台机器可能看到这个广播,都在数据链路层。
3. DNS:从域名到 IP 的翻译官
3.1 域名层级与解析流程没有想象中复杂
DNS 把域名交给了分布式数据库来管理,而不是一台机器存全量。域名从右往左看,.后面是根域,再往左是顶级域,再往左是二级域名、三级域名。以www.example.com为例,.com是顶级域,example.com是授权域名,www是主机记录。
解析流程分为两步:递归查询和迭代查询。用户的设备通常只向本地配置 DNS 服务器发起一次递归查询,意思是“你把 www.example.com 的地址找到给我”;本地 DNS 收到后,自己向上级一级一级迭代询问:问根服务器“.com的权威服务器是谁”,得到答案后再问.com权威服务器“example.com的权威服务器是谁”,最后再问example.com的权威服务器“www这个记录是什么”。整个链条拿到 IP 后,再层层返回给发起方。
你可以直接看这个过程:
dig +trace www.example.com+trace会从根服务器开始,把所有迭代查询过程完整打出来。第一次跑这个命令的人几乎都会有一种“原来如此”的感受。抓包时也会发现,默认 DNS 查询走 UDP 53 端口,响应同样走 UDP,如果应答太大才会切到 TCP。
3.2 常见记录类型速查表
DNS 记录类型是日常运维出现频率最高的知识点,整理一份速查表方便查阅:
| 记录类型 | 作用 | 使用场景 |
|---|---|---|
| A | 域名指向 IPv4 地址 | 最基础的主机记录 |
| AAAA | 域名指向 IPv6 地址 | IPv6 环境使用 |
| CNAME | 域名别名指向另一个域名 | CDN 接入、子域名关联 |
| MX | 指定邮件服务器 | 邮箱收发路由 |
| NS | 指定该域名的权威服务器 | 域名托管节点声明 |
| TXT | 任意文本信息 | 域名验证、SPF 反垃圾邮件 |
CNAME 记录在 CDN 场景下特别重要。你想让某个域名接入 CDN,通常不需要修改 IP,而是把域名 CNAME 到 CDN 服务商生成的域名上,比如xxxx.examplecdn.com。CDN 服务商通过这个统一入口来做调度,后续修改边缘节点 IP 时你完全不用跟着变更。
3.3 缓存、TTL 和“为什么改了 DNS 不生效”
DNS 之所以快,是因为缓存;DNS 之所以给人添麻烦,也是因为缓存。
每一条 DNS 记录都带一个 TTL(存活时间),单位是秒。TTL 越大,缓存时间越久,对权威服务器的压力越小,但出问题后生效越慢。比如你早上把网站 IP 改了,下午还想让全量用户访问到新地址,前提是各地解析器都愿意抛弃旧缓存。如果你原来 TTL 设置了 86400 秒,那么有些人最长 24 小时都会访问旧 IP,这是毫无办法的。
所以经验丰富的运维在搬迁 IP 或切流之前,会提前把 TTL 调小,比如调到 300 秒,等生效稳定后再调回来。本地排查时,先刷新主机缓存:
# Windows ipconfig /flushdns # Linux(不同发行版命令不同) sudo systemd-resolve --flush-caches再检查实际解析出来的结果:
dig www.example.com +noall +answer注意dig输出里会带一列 TTL,如果它显示的数字很小,说明对端把 TTL 设低了,属于正常现象;如果 TTL 已经归零,但你访问时仍然拿到旧 IP,那多半是浏览器内部的 DNS 缓存还在起作用,不是系统问题。
3.4 DoH 和内网解析,一个容易被忽略的新变化
这几年浏览器和操作系统逐渐默认启用加密 DNS,也就是 DoH(DNS over HTTPS),目的很单纯:让 DNS 查询内容不被网络路径上的中间设备窥探和篡改。但部署了内网域名的企业和学校,经常会被这个“默认安全”折腾得够呛。
表现就是:办公电脑上浏览器打不开内网网站,但用命令行nslookup却能解析出正确结果。原因往往是浏览器走了 DoH,绕过了公司内网 DNS,导致解析不到内网域名。排查时先关闭浏览器里的“安全 DNS”选项,或者把它改成“使用当前系统 DNS 服务”,问题通常立刻消失。
这个现象说明,DNS 技术在演进,但排查思路依然不变:先确认你问的是谁,再确认它从哪儿拿到的答案。
4. CDN:让访问不再“舍近求远”
4.1 CDN 到底解决了什么问题
没有 CDN 的年代,全球用户访问同一个源站 IP,请求全部涌向同一个机房。跨地域、跨运营商的网络链路往往存在高延迟和拥塞,图片和视频类大文件体验极差。
CDN 做的事很简单:把内容复制到遍布各地的边缘节点上,让用户从最近的节点获取数据。所谓“最近”可以从两个维度理解,一是地理上的距离,二是网络路径上的 RTT 时延。源站只负责回源供给,边缘节点才是面向用户的“店面”。
你打开一个网页,页面引用了一张商品图,浏览器请求的是图片的 URL;CDN 会判断这个 URL 的资源在自己这有没有,有就直接返回,没有就回源站拿一份,然后缓存到本地,下次再有同一地区用户请求时就不用再回源。这个流程最终换来的是更低的延迟和更小的源站压力。
4.2 核心机制:GSLB 调度与回源
CDN 的关键在于“用户接通到哪个节点”这件事由谁来定。绝大多数 CDN 靠 DNS 调度完成。域名接入 CDN 后,权威 DNS 并不是直接返回源站 IP,而是根据递归解析器的来源 IP,判断用户大概在哪个区域,然后返回该区域最优边缘节点的 IP。这个全局负载均衡服务就是 GSLB。
比如一个在上海的用户请求域名,CDN 的权威 DNS 看到递归解析器来自华东地区,就返回给用户一个上海边缘节点 IP;一个在四川的用户请求同样的域名,则可能被导向成都节点。这个判断依据比较粗,因为递归解析器通常不在用户同一台机器上,但区域粒度已经足够用了。
可以用dig +short再看一层信息:
dig +short www.example.com如果域名接入了 CDN,返回的 IP 通常是 CDN 服务商的节点地址。再继续查:
host <上面查到的IP>反向解析结果往往能看出它属于哪个机房或哪个运营商,这也是定位“为什么我访问这么慢”的常用手段。
4.3 缓存策略与命中率
CDN 节点不是无脑缓存所有东西,它需要源站配合。HTTP 响应头里的Cache-Control是整个缓存逻辑的核心控制位。
Cache-Control: max-age=3600表示资源可以缓存 3600 秒,在这段时间内边缘节点直接返回缓存内容。如果源站返回Cache-Control: no-store,CDN 即便把内容缓存在了本地,也不会直接输出给用户,每次都必须回源拿最新版本。写给静态资源加缓存策略时,常配合文件名中的 hash 来更新:app.a1b2c3.js的内容变了,文件名也跟着变,CDN 会把它当成一个新 URL,自动绕开旧缓存。
看一个资源是否被 CDN 缓存,可以抓响应头:
curl -sI https://cdn.example.com/static/app.js重点关注x-cache、via、age这些扩展头。比如x-cache: HIT表示命中缓存,x-cache: MISS表示未命中,age: 500表示这个缓存已经存在了 500 秒。如果你看到大量 MISS,说明 CDN 的缓存策略没有生效,或者你的资源本身不适合缓存。
4.4 实操:查一次 CDN 调度路径
在本地执行一个常规验证流程,基本可以把“CDN 有没有生效、节点在哪、缓存命中没有”一次查清:
# 第一步:解析看看返回什么 IP dig +short www.example.com # 第二步:追踪路由看路径是否符合预期 traceroute www.example.com # 第三步:查看响应头确认命中状态 curl -sI https://cdn.example.com/static/app.js如果dig返回的 IP 明显不在你所在城市或区域,说明 GSLB 调度可能把你分配到了远处,此时可以继续查看traceroute的路径,确认中间是否跨了异常节点。如果返回的是源站 IP,说明域名根本没接入 CDN,后续就不用纠结缓存头了。
这一步比较适合在办公网络和家庭网络里各跑一次,你会明显看到 IP 和路径的差异,对 CDN 调度的理解会立刻立体起来。
4.5 现代 CDN 不只是缓存静态资源
早期 CDN 几乎等于图片缓存,现在的 CDN 已经覆盖了动态请求加速、页面性能优化、WAF 防护等能力。一些动态接口无法静态缓存,CDN 会通过优化传输协议、智能选路、连接复用等方式降低回源链路损耗,也能做到显著的加速效果。
做过实际站点迁移的人都知道,CDN 带来的收益一半在缓存命中,另一半在链路质量改善。即便动态内容每次都要回源,如果 CDN 边缘节点与源站之间的内部专线质量远优于用户到源站之间的公共链路,整体时延依然会下降不少。这也是我在评估一个站点是否需要上 CDN 时,不只盯住“图片是否多”,还会看用户分布和源站网络质量的原因。
5. 常见问题排查与避坑实录
5.1 MAC/IP 故障速查表
| 现象 | 大概率原因 | 快速处理 |
|---|---|---|
| DHCP 获取不到地址,IP 变成 169.254.x.x | 路由器 DHCP 服务异常或网线/无线连接有问题 | 重启路由器,检查物理链路 |
| 提示 IP 地址冲突 | 局域网内另一台设备被手动配置了相同 IP | 找到冲突设备改为自动获取,或改 IP |
| 局域网内响应时通时断 | 交换机 MAC 表抖动或回路问题 | 排查是否出现环路,确认网关 ARP 表正常 |
| 更换新电脑后无法上网 | 网络接入绑定过旧电脑 MAC | 在新电脑上临时修改 MAC 为旧值 |
关于 169.254.x.x,还有一个新手容易踩的坑:看到这个地址就以为网卡坏了,其实它叫链路本地地址,是操作系统无法通过 DHCP 拿到 IP 时的兜底方案,仅用于同网段广播通信。排查时先确认 DHCP 服务是否正常,再检查网线、无线信号,别一上来就重装驱动。
5.2 DNS 问题排查清单
遇到“域名打不开”,我习惯从本地往上游逐层排查,在哪个环节断了就处理哪里。
先看 hosts 文件有没有被写入奇怪的映射。这个文件优先级最高,一旦被写入错误映射,什么缓存刷新都没用。其次检查系统配置的 DNS 服务器地址,Windows 下用ipconfig /all,Linux 下看/etc/resolv.conf。如果配置的是某个内网 DNS,可能解析不了公网域名,换一个知名公共 DNS 对比测试是最快的定位方法。再检查域名本身有没有过期,用whois查注册状态,很多业务故障最后发现是域名到了续费期但没续上。最后别忘了查看权威服务器是否正常响应,用dig NS确认一下。
这套流程基本能拿下 80% 的问题。我见过不少人大半天排查不出来的故障,最后发现是 hosts 文件里残留了一行旧注释里带空格的无效映射,看起来无关紧要,却让解析走向完全错误。
5.3 CDN 问题:为什么命中了还慢
按经验排一下 CDN 问题的优先级:缓存未命中排在第一位,其次是节点离用户太远,再次是源站本身链路差,最后才是用户侧网络问题。
命中了还慢的情况我也遇到过很多次,最大嫌疑是“命中的数据内容太大”或者“用户到节点之间跨运营商严重”。比如你人在联通网络,CDN 节点却分到了电信机房,两家之间的互联带宽往往在高峰期非常紧张,即便物理距离不远,延迟也可能很高。这时看traceroute,如果路径上出现明显的高延迟跳点,可以直接联系 CDN 服务商调整调度策略。
刷新 CDN 缓存也是一个经典坑。我把修改后不生效的问题排在首位,因为很多人以为刷新了 CDN 缓存,实际他们只刷新了浏览器缓存。正确做法是在 CDN 控制台发起 URL 刷新,等待进度完成,再用curl加时间戳参数重新验证:curl -sI "https://cdn.example.com/app.js?v=20250101",如果返回头中age归零,说明确实回源重新缓存了。
5.4 一套适合初学者的动手实验思路
如果你的实验室条件不多,一台电脑至少也能完成整套第一课的动手验证,不需要服务器,不需要域名,只需要终端和抓包工具。
第一步,用ip addr或者 Windows 的ipconfig查看本机 IP 和网关,算出你所在网段,并手动算一下可用的主机范围。第二步,arp -a查看 ARP 表,然后清空缓存并 ping 一次网关,观察 ARP 表如何重新建立,配合tcpdump抓 ARP 过程。第三步,对任意一个日常访问的域名执行dig +trace,记录从根服务器开始的每一级应答,画出完整的解析链路。第四步,用curl -sI访问一个自己经常访问的网站静态资源,观察响应头里的缓存字段,判断它是否经过了 CDN。
这四步全部做完,你对网络基础的理解会比看十遍教材都牢固。它们不会消耗太多时间,但每个步骤都在强迫你回答一个核心问题:刚才发生的到底是哪一层的事情。
结尾:一点个人体会
我带新人时,最后总会留同一个作业:找一台电脑,打开 Wireshark,清空所有过滤条件,访问一个简单的网页,然后抓包十分钟,试着只用已经掌握的网络知识解释自己在抓包里看到的每一个关键帧。能解释 ARP 的广播请求,能说清 TCP 三次握手时源 IP 和目标 IP 为什么不变,能指出 DNS 和 CDN 在响应速度上做了什么贡献,这一课就算真正过关了。网络基础不是背出来的,是用命令和抓包喂出来的。等你亲手看到了 MAC 地址在每一跳更新、看到了 DNS 响应头里的 TTL 从大到小变化、看到了 CDN 节点替你挡掉一次回源,你才算真的懂。