当在浏览器中输入百度地址后,发生了什么?(计算机网络篇)
1. 前言
当在浏览器中输入百度地址后,发生了什么?一般可以分为以下几个步骤
- 将域名www.baidu.com 解析为IP地址
- 浏览器所在主机和服务器建立TCP/IP连接
- 浏览器向服务器发送http请求
- 服务器处理http请求,并生成html文件返回
- 浏览器解析html文件,渲染页面
从计算机网络的角度讲,仍然有许多问题,比如
- DNS是如何解析的?
- 为什么使用TCP连接?
- TCP的数据是如何封装的?
- 如果服务器宕机了会发生什么情况?
- 从主机到服务器会经过哪些设备,这些设备仅仅只是转发请求吗?
计算机网络详细阐述了这些细节,现在让我们一探究竟。
2. 网络细节
2.1.DHCP和自动配置
当我想要发送快递,快递员会问我,你家在哪里?你家附近最近的邮局在哪里?
一个系统能够在Internet上运行并提供常用服务的基本要素包括:一个IP地址和子网掩码(用于获取子网信息),以及DNS 服务器和路由器的IP地址。那这些数据从哪里获取呢?这里就需要用到DHCP协议(Dynamic Host Configuration Protocol)。
先来看看DHCP的流程:
注:一般路由器都附带DHCP服务功能
流程说明:客户机向DHCP服务器申请IP地址以及其他信息,申请成功后进行验证(见2.4)。但是这个IP是有有效期的,这里引入了租约的概念,即在IP即将失效之前进行续租。租约的概念在计算机领域广泛使用,比如分布式锁。
2.2.DNS解析
我的快递要发往上海的同事,但是他住在哪里呢?
对主机来讲,它并不知道www.baidu.com 是什么,需要一种机制将其转换为IP地址,这里我们引入了DNS系统。DNS系统可能是当今世界最庞大的分布式系统之一。我们先来看看它的设计。
整个流程如下
- 主机会先尝试在本地进行解析,linux中可以在文件/etc/hosts中配置DNS映射
- DNS请求会转发给缓存/转发服务器
- DNS请求发送给ISP(Internet Service Provider,比如电信,联通)
- ISP先访问根域名服务器,根域名服务器返回gTLD 服务器(Generic top-level domain)
- ISP 访问gTLD服务器,gTLD服务器 返回二级域名服务器
- ISP 访问二级域名服务器,二级域名服务器根据域名解析IP地址,返回给ISP
- ISP 将IP地址按原路返回给主机
2.2.1 模拟
在linux系统中,我们可以使用如下命令进行模拟,以下响应部分返回了一个完整的DNS响应。
➜ ~ dig www.baidu.com
; <<>> DiG 9.10.6 <<>> www.baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62055
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 5, ADDITIONAL: 9
;; QUESTION SECTION:
;www.baidu.com. IN A
;; ANSWER SECTION:
www.baidu.com. 1183 IN CNAME www.a.shifen.com.
www.a.shifen.com. 600 IN A 14.119.104.254
www.a.shifen.com. 600 IN A 14.119.104.189
;; AUTHORITY SECTION:
a.shifen.com. 585 IN NS ns2.a.shifen.com.
a.shifen.com. 585 IN NS ns5.a.shifen.com.
a.shifen.com. 585 IN NS ns3.a.shifen.com.
a.shifen.com. 585 IN NS ns4.a.shifen.com.
a.shifen.com. 585 IN NS ns1.a.shifen.com.
;; ADDITIONAL SECTION:
ns2.a.shifen.com. 814 IN A 220.181.33.32
ns3.a.shifen.com. 248 IN A 112.80.255.253
ns3.a.shifen.com. 248 IN A 36.152.45.198
ns4.a.shifen.com. 300 IN A 14.215.177.229
ns4.a.shifen.com. 300 IN A 111.20.4.28
ns5.a.shifen.com. 214 IN A 180.76.76.95
ns1.a.shifen.com. 814 IN A 110.242.68.42
ns5.a.shifen.com. 214 IN AAAA 240e:bf:b801:1006:0:ff:b04f:346b
ns5.a.shifen.com. 214 IN AAAA 240e:940:603:a:0:ff:b08d:239d
;; Query time: 8 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Fri Jun 02 09:08:16 CST 2023
;; MSG SIZE rcvd: 348
➜ ~
有个有趣的问题,既然我们可以通过域名查找到IP,那么能否根据IP查找到域名呢?答案是可以的, ptr技术可以帮我们做到这一点。因篇幅有限,本文不详细展开。
2.2.3 DNS服务器的部署
DNS服务器一般至少有两台,做到高可用。当主DNS服务器发生变化时(比如调整域名映射),会将变化数据同步到其他辅助服务器,这个过程称为区域传输。区域传输也分为完整区域传输和增量区域传输。全量和增量传输的概念使用非常广泛。
2.3.IP数据报
快递员会将我们的物品打包成打包盒。
IP协议将http请求数据封装成IP数据报,并采取尽力而为的策略,即IP协议并不保证数据报的正确性。整个通信链路的大小(MTU)是有限制的,IP请求会被切分成多个数据报。
最大传输单元(英语:Maximum Transmission Unit,缩写MTU)是指链路层上面所能通过的最大数据包大小(以字节为单位)。最大传输单元这个参数通常与通信接口有关(网络卡、串口等)。
2.3.1 IPv4请求头
请求头的其他细节我们不进行赘述,只需要关注ttl
Time to Live(ttl),即最大生存期,IP数据报每经过一个路由器该值减1,到0后该数据报不会被转发。
2.3.2 IP转发流程
假设IP路由表如下:
目的地 | 掩码 | 网关(下一跳) | 接口 |
0.0.0.0 | 0.0.0.0 | 10.0.0.1 | 10.0.0.100 |
10.0.0.0 | 255.255.255.128 | 10.0.0.100 | 10.0.0.100 |
对目的IP为10.0.0.9的数据包而言,以上两条路由都符合,但是根据最长匹配原则,该数据报的下一跳是10.0.0.100。
10.0.0.9 ^ 0.0.0.0 = 0.0.0.0
10.0.0.9 ^ 255.255.255.128 = 10.0.0.0 # 10.0.0.9 和 10.0.0.0 匹配得更好
2.4.链路层转换
根据地图我知道寄件地址在上海的岳家嘴小区,但是我的卡车司机在哪里?
ARP协议(Address Resolve Protocol) 提供了一种目标IP地址到MAC地址(Media Access Control Address)的转换过程。注意ARP 协议仅适用于IPv4,IPv6使用邻居发现协议。
2.4.1 ARP 协议流程
- 主机发送ARP请求(包含目标IP)进行广播(链路层广播):“如果你将IPv4地址配置为自己的地址,请向我回应你的MAC地址”
- 目标主机向源主机直接返回ARP响应(包含目标MAC)
- 源主机收到MAC地址,并进行缓存
- 同时目标主机也进行MAC地址缓存。
使用如下命令可以查看ARP缓存信息:
➜ ~ arp -a
? (192.168.0.1) at 80:ea:7:ea:b:b4 on en0 ifscope [ethernet]
? (192.168.0.100) at 88:64:40:10:7a:b5 on en0 ifscope [ethernet]
? (192.168.0.101) at 68:2f:67:94:63:44 on en0 ifscope permanent [ethernet]
? (192.168.0.102) at 64:ff:a:dc:db:51 on en0 ifscope [ethernet]
? (192.168.0.104) at 58:41:20:da:a6:c9 on en0 ifscope [ethernet]
? (192.168.0.105) at 96:17:e7:12:9d:f3 on en0 ifscope [ethernet]
? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet]
? (239.255.255.250) at 1:0:5e:7f:ff:fa on en0 ifscope permanent [ethernet]
2.4.2 ARP的其他用途
试想一下,如果主机使用ARP广播自己的IP地址会发生什么情况?
- 如果其他主机也配置了相同的IP,那么就会返回一个错误,这样可以进行地址冲突检测(ACD)
- 如果其他主机缓存了源主机的过期MAC,收到ARP请求后,将会更新源主机的MAC地址
2.5.ICMP协议
我的快递丢包了,谁能告诉我发生了什么?
计算机网络提供了ICMP协议(Internet Control Message Protocol),提供差错信息,查询响应信息。ICMP报文对IP传输过程中出现的问题进行补充说明,位于网络层和传输层之间。
常见ICMP报文如下:
报文类型 | 报文 | 说明 |
差错报文 | 主机不可达 | 比如主机已经关闭,或者ARP请求错误 |
差错报文 | 无路由 | 没有合适的下一跳路由(参考IP转发流程) |
差错报文 | 端口不可达 | 主机可达,但是端口不可用 |
差错报文 | PTB(packet too big) | 超过了MTU |
差错报文 | 重定向 | 更好下一跳路由,帮助源主机更好的路由 |
差错报文 | ICMP超时 | ttl减小到0,不再进行转发 |
查询/信息类 | ping | 查看从源主机到目标主机的连通性 |
查询/信息类 | 路由器发现 |
使用traceroute命令可以查看ICMP超时细节:
➜ ~ traceroute www.baidu.com
traceroute: Warning: www.baidu.com has multiple addresses; using 14.119.104.189
traceroute to www.a.shifen.com (14.119.104.189), 64 hops max, 52 byte packets
1 192.168.0.1 (192.168.0.1) 1.467 ms 1.210 ms 1.155 ms
2 192.168.1.1 (192.168.1.1) 2.859 ms 1.881 ms 1.892 ms
3 100.64.0.1 (100.64.0.1) 5.186 ms 5.496 ms 5.081 ms
4 111.175.212.197 (111.175.212.197) 10.565 ms 12.981 ms 16.398 ms
5 111.175.222.245 (111.175.222.245) 10.878 ms 6.432 ms 5.151 ms
2.6.防火墙和NAT
如何防止运送管制物品(比如刀具)?如果快递路径比较长,涉及多个快递公司怎么办?
2.6.1 防火墙
一般使用防火墙来解决非法流量的问题,防火墙给人一种厚实的感觉,似乎是一种非常复杂的软件,但其实防火墙本质上是一种过滤器或者代理。防火墙分为代理防火墙和包过滤防火墙。
- 包过滤防火墙,本质上是一种过滤器,能够过滤一些网络流量,可以配置为丢弃或转发数据包头部中符合或者不符合特点标准的数据包。
- 代理防火墙,在防火墙机器上运行每个受支持的服务的应用/服务代理。代理防火墙分为http代理防火墙(类似于nginx)和socks防火墙(会话层)。
2.6.2 NAT (Network Address Translation)
上图中左侧是内网,右侧是外网。当内网的机器需要访问外网的时候,就必须经过NAT。
- 发送数据包时,NAT会数据包的源地址修改为公共IP地址。
- NAT 收到外网服务器返回的数据包时,会将数据包的目标地址修改为源主机的内网IP
由于各种协议有着不同的实现,所以NAT 对各类协议的支持也各不相同,比如TCP是面向连接的,NAT 会使用 NAT session, NAT mapping, port reservation 等技术来支持TCP,并且还需要解决TCP的分片问题。
2.6.3 使用iptables 配置防火墙
# 从ipv4地址 0.0.0.0 进来的udp流量,以及目的地采用dhcp端口号(67,68)的本地/子网广播流量,都经由内部接口被允许通过。
iptables -A INPUT -i eth0 -p udp -s 0.0.0.0 --sport 67 -d 255.255.255.255 -dport 68 -j ACCEPT
2.7.UDP
在美国有种最便宜的快递服务,不负担任何追踪或者保障
UDP(User Datagram Protocol)协议是一种保留消息边界的面向数据包的传输层协议,不提供差错纠正。
UDP协议头部如下:
校验和使用crc32校验。
鉴于UDP廉价的性能,一种使用UDP的常见方法是,使用UDP进行PMTUD(Path Maximum Transmission Unit Discovery)。
2.7.1 创建UDP 服务
这里我们使用sock程序来创建UDP服务:
sock程序下载地址(http://www.icir.org/christian/sock.html),该程序需要进行编译
sock -u -s 7777
[root@iZbp1hh62zkt10csxrr34uZ ~]# netstat -l --udp -n
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 0 0 0.0.0.0:7777 0.0.0.0:*
2.8 TCP
我希望快递公司能提供可靠,可追踪的服务,能和我随时保持联系。
TCP(Transmission Control Protocol)是广泛使用的可靠的面向连接的传输协议。
2.8.1 TCP连接管理
- 众所周知,TCP使用三次握手来创建连接,四次挥手来断开连接。四次挥手的主要原因是TCP是全双工的,可能只有一方主动断开连接不再发送数据,但是仍然在接收另一方的数据。
- 同样的,TCP也会受到MTU的限制,当TCP报文段大小超过MTU时,会得到一个ICMP差错消息PTB.
- 当连接被异常终止时,会返回一个RST报文段。
TCP有许多有意思的选项
- 最大段大小(MSS), 即允许从对方接收到的最大报文段
- 选择确认(SACK),用于快速重传,补上分组空洞 (2.8.2)
- 窗口缩放(WSCALE),即告知连接的另一方自己可用窗口的变化 (2.8.3)
2.8.1.1 模拟
同样的,我们使用sock程序来模拟TCP连接操作,并使用wireshark 抓包
# 服务器
sock -i -s -v -p 20 6666
# 客户机
telnet 120.26.97.171 6666
2.8.2 TCP 超时与重传
既然TCP要保证可靠,那么它就必须处理超时和重传的问题。首先我们理解一个概念, RTT(Round trip time),即一个数据包发送到响应的时间间隔,这个时间在计算RTO(retransmission timeout)时会用到。
TCP有两种重传方式:
- 超时重传,当等待的时间超过RTO,就会进行重传,并且采用指数退避的方式。(指数退避的方式被广泛使用,比如spring-retry).
- 快速重传,根据SACK进行快速重传。接收方告诉发送方我缺了哪些分组序列,然后发送方优先发送这些缺失的序列。
2.8.3 数据流和窗口
我们可以理解为发送方和接收方都有一个缓冲队列(其实是窗口),这个队列的可用部分会随时发生变化(双方应用程序消费消息的速度可能一直在变化),那么发送方和接收方需要及时地告知对方,以确保彼此不会发送超过对方队列可用部分大小的报文段。
为了提升发送效率,TCP引入Nagel算法,当TCP连接中有在传数据时,小的报文段不能被发送,需要等待更多的数据一起发送。这一点和批量发送比较类似,但是做得比较智能。
2.8.3 TCP拥塞控制
拥塞指的是,路由器因无法处理高速率达到的流量而被迫丢弃数据的现象。这往往意味着网络异常繁忙,如果这个时候我们继续按照原始速率发送消息,那么将会出现很多丢包,继而引发超时和重传,会极大的降低发送效率。
TCP提供两种方式来解决拥塞控制:
- 慢启动,TCP连接刚开始时,会慢慢地提高发送分组的速度,比如说以2的倍数增长,直到出现丢包的情况下进行回退。然后进入拥塞避免阶段。
- 拥塞避免,进入此阶段后,TCP发送分组的速度呈现线性增长,直到达到最佳的发送速率。
2.8.3 TCP 保活机制
许多组件会使用keepalive机制,这里可以参考一下TCP的保活设计:
经过某一设定时间(keepalive time)后, 每间隔一段时间(keepalive interval)进行保活探测, 一共探测N(keepalive probe)次
2.9 组播和广播
我想给我的一些朋友们同时发送节日贺卡。
网络中的组播和广播提供此类功能,一般使用UDP协议。
三.总结
很多人觉得计算机网络在工作开发中用不到,他们会争辩说我又不是运维,其实不然,
- 计算机网络在我们的工作中无处不在,任何一个组件都会和其他组件进行网络通信,在我们遇到一些问题时,比如,“connection reset by peer”, “主机不可达”,会有个大概的思路,心里有张地图。
- 如果想做到专家级别,那么深入网络也是非常必要的,计算机网络规定了协议,然后有了多种实现,然而在实际工作中,在流量很高的情况下,标准配置可能并不是最佳的。能根据实际问题选择最合适的方案,才是我们追求的目标。
- 一项技术有没有参考价值,就看它解决了什么问题,比如DNS系统,TCP协议解决的问题,远比我们现实开发工作中碰到的问题更复杂,更直指核心。我们可以从前辈们的设计中汲取灵感,帮助我进行方案设计。
太阳底下无新鲜事,我们所遇到的问题,前辈们早就遇到了。