-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在浏览器地址栏输入回车键, 后面都发生了什么? #94
Comments
DNS 解析上面我们讲述了最小的实验网络,本地点对点的浏览器服务器间的请求过程。浏览器之前通过IP找到服务器请求数据。但是实际使用过程中,我们通常是用域名来请求一个网页的,如:www.baidu.com。从www.baidu.com 到 可以请求数据的 IP 的映射过程就是 DNS 的解析过程。 设备(电脑、手机等)通过Wi-Fi、移动网络接入网络的同时,网络运营商会给你分配一个IP地址,这个地址可能是固定的,也可能每次登录的时候都会变化。假如你要访问 www.baidu.com , 显然你无法直接获取到其真正的IP地址。 域名形式域名是是一个由 “.” 构成的富有层次结构的地址。 这里插一点, 域名除了能代替IP地址,还有很多其他的用途。在apache,nginx 这样的web 服务器里,域名还可以用来标识虚拟主机,决定哪个虚拟主机来对外提供服务,例如nginx 中的“server_name”: server {
listen 80; # 监听 80 端口
server_name www.baidu.com; # 主机名是 www.baidu.com
...
} 域名解析DNS 的核心系统是一个三层的树状、分布式的服务器, 分别是
假如你要访问 www.baidu.com ,就要进行下面的三次查询:
域名“缓存”虽然核心服务器遍布全球且足够稳定,但也架不住全球这么多人同时访问网络。所以很多大公司或者网络运行商都有自己的DNS服务器(非权威域名服务器),代替用户访问核心 DNS 系统。非权威域名服务器可以缓存之前访问过的记录。如有记录则无需向根服务器发起查询。 非权威域名服务器往往比核心系统数量要多很多,而且大多部署在离用户较近的位置。 除了非权威域名服务器外,操作系统也会对DNS解析结果进行缓存,如果你曾经访问过该地址,操作系统就会记录下该IP,下次直接访问。 另外本地还有一个host 文件,在操作系统缓存中找不到某地址时,操作系统会找这个文件。 在 Nginx 里有这么一条配置指令“resolver”,它就是用来配置 DNS 服务器的,如果没有它,那么 Nginx就无法查询域名对应的 IP,也就无法反向代理到外部的网站。 resolver 8.8.8.8 valid=30s; # 指定 Google 的 DNS,缓存 30 秒 域名其他用处
|
响应状态码1XX1XX 类状态码属于提示信息,是协议处理的中间状态,实际能够用到的时候很少。 2××2×× 表示服务器收到并成功处理了客户端的请求。
状态码 206 通常还会伴随着头字段“Content-Range”,表示响应报文里 body 数据的具体范围,供客户端确认,例如“Content-Range: bytes 0-99/2000”,意思是此次获取的是总计 2000 个字节的前100 个字节。 3××3××表示客户端请求的资源发生了变动,客户端必须用新的 URI 重新发送请求获取资源,也就是通常所说的“重定向”,包括著名的301、302 跳转。
4××4××类状态码表示客户端发送的请求报文有误,服务器无法处理,它就是真正的“错误码”含义了。
5××5×× 类状态码表示客户端请求报文正确,但服务器在处理时内部发生了错误,无法返回应有的响应数据,是服务器端的“错误码”。
|
HTTP的连接管理短链接
长链接长链接就是 早上打开打开机盖子,直到晚上下班后再关上,期间可以自由打卡,节约时间。 连接相关的头字段长连接因为长时间不关闭,服务器iu必须要在内存中保存他的状态,导致占用服务器资源。如果大量的占用资源而不用,很快服务器资源就会被耗尽,导致真正服务器无法为真正需要资源的人提供服务。 所以,长链接也需要在恰当的时候关闭,在请求头里加上“Connection: close”字段,告诉服务器:“这次通信后就关闭连接”。服务器看到这个字段,就知道客户端要主动关闭连接,于是在响应报文里也加上这个字段,发送之后就调用 Socket API 关闭 TCP 连接。 服务器端通常不会主动关闭连接,但也可以使用一些策略。拿 Nginx 来举例,它有两种方式:
队头阻塞因为http规定报文必选是“一发一收”,这就形成了一个先进先出的串行队列。队列内部没有轻重缓急的优先级,只有入队的先后顺序,排在前面的请求被最先处理。 如果队首的请求因为处理的太慢耽误了时间,那么后面的所有请求都需要等待,浪费本不应该浪费的时间。 比如某天,打卡机突然坏了,及时第一个人急的满头大汗修好了机器后面的人也都迟到了。 性能优化机器都会有坏的可能,没有办法只能缓解,公司只能多买两天打卡机放在前台。在 HTTP 里就是“并发连接”(concurrent connections),也就是同时对一个域名发起多个长连接,用数量来解决质量的问题。 但这种方式也存在缺陷。如果每个客户端都想自己快,建立很多个连接,用户数×并发数就会是个天文数字。服务器的资源根本就扛不住,或者被服务器认为是恶意攻击,反而会造成“拒绝服务”。 所以,HTTP 协议建议客户端使用并发,但不能“滥用”并发。RFC2616 里明确限制每个客户端最多并发 2 个连接。不过实践证明这个数字实在是太小了,众多浏览器都“无视”标准,把这个上限提高到了 6~8。 但“并发连接”所压榨出的性能也跟不上高速发展的互联网无止境的需求,还有什么别的办法吗? 公司发展的太快了,员工越来越多,上下班打卡成了迫在眉睫的大问题。前台空间有限,放不下更多的打卡机了,怎么办?那就多开几个打卡的地方,每个楼层、办公区的入口也放上三四台打卡机,把人进一步分流,不要都往前台挤。 这个就是“域名分片”(domain sharding)技术,还是用数量来解决质量的思路。 HTTP 协议和浏览器不是限制并发连接数量吗?好,那我就多开几个域名,比如 shard1.chrono.com、shard2.chrono.com、shadr3.chrono.com 而这些域名都指向同一台服务器 www.chrono.com ,这样实际长连接的数量就又上去了,真是“美滋滋”。 |
前期准备
为了方便分析数据,我们先来看一下最简单的本地 点对点数据请求。
sudo vim/etc/host
配置host 文件:为了可以抓到 tcp/ip 包,本次我们采用的抓包工具是Wireshark.
抓包分析
在浏览器地址栏输入127.0.0.1后,Wireshark 抓到14个包。如下
最开始的3个包,浏览器使用的端口是 52085, 服务器使用的端口是 80,经过SYN, SYN/ACK, ACK 的三个包后,浏览器与服务器的 tcp 连接即建立起来了。 (4-6 非80端口的内容可以忽略不看)
有了可靠的 tcp 连接通道后, http 协议就可以开始工作了。于是,于是浏览器按照http协议规定的格式,通过tcp 发送了一个
GET HTTP/1.1
的请求报文。(上图7条)随后,web 服务器回复了第8个包。 在TCP 协议层面确认:“收到报文”。这条信息,HTTP层面看不到。
web 服务器收到报文后在内部也要处理这个请求。同样也是依据HTTP协议的规定,解析报文,可靠浏览器发送这个请求想要干什么。
他一看,原来是要获取根目录下的默认文件,好吧,那我就从磁盘上把这个文件读出来,早拼成符合HTTP格式的报文,发回去吧. 这就是第9个包, “HTTP/1.1 200 OK” ,底层走的还是TCP 协议。
同样的,浏览器也要给服务器回复一个 TCP 的 ACK 确认。 “收到响应”, 10包。
这时浏览器收到响应后,也要根据
Content-Type
等字段分析一下, 服务器的返回的文件的内容格式。本文中返回的是html 文件,那就调用排版引擎、JavaScript 引擎等处理一下,然后在窗口返回需要展示的内容。之后还有2个一样的来回是请求“favicon.io” 的,本例,没有所以返回了404。
ps: 如果不是http 1.1 这样的长链接,还会存在”4次挥手“ 的情况,整个过程如下图:
总结:
The text was updated successfully, but these errors were encountered: