You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
当然本文主要不是介绍硬件与操作系统中的细节,前言只是想说明,从输入 URL 到浏览器展现结果页面之间有太多底层相关的知识,怀着一颗敬畏的心并且在有限的篇幅中是无法详细阐述的,所以本文会将关注点放在在一个稍高的角度上来看,从浏览器替我们发送请求之后到看到页面显示完成这中间中发生了什么事情,比如 DNS 解析、浏览器渲染。
. 388687 IN NS m.root-servers.net.
. 388687 IN NS d.root-servers.net.
. 388687 IN NS h.root-servers.net.
. 388687 IN NS l.root-servers.net.
. 388687 IN NS c.root-servers.net.
. 388687 IN NS g.root-servers.net.
. 388687 IN NS a.root-servers.net.
. 388687 IN NS k.root-servers.net.
. 388687 IN NS i.root-servers.net.
. 388687 IN NS e.root-servers.net.
. 388687 IN NS f.root-servers.net.
. 388687 IN NS j.root-servers.net.
. 388687 IN NS b.root-servers.net.
;; Received 1097 bytes from 100.100.2.138#53(100.100.2.138) in 1072 ms
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
;; Received 1174 bytes from 192.5.5.241#53(f.root-servers.net) in 1841 ms
google.com. 172800 IN NS ns2.google.com.
google.com. 172800 IN NS ns1.google.com.
google.com. 172800 IN NS ns3.google.com.
google.com. 172800 IN NS ns4.google.com.
;; Received 664 bytes from 192.12.94.30#53(e.gtld-servers.net) in 185 ms
www.google.com. 300 IN A 216.58.200.228
;; Received 48 bytes from 216.239.34.10#53(ns2.google.com) in 2 ms
所以总的来说,DNS 的解析是一个逐步缩小范围的查找过程。
建立 HTTPS、TCP 连接
确定发送目标
拿到 IP 之后,还需要拿到那台服务器的 MAC 地址才行,在以太网协议中规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须要知道目标主机的 MAC 地址。所以根据ARP(根据 IP 地址获取物理地址的一个 TCP/IP 协议)获取到 MAC 地址之后保存到本地 ARP 缓存之后与目标主机准备开始通信。具体细节参见维基百科 DHCH/ARP。
建立 TCP 连接
为什么握手一定要是三次?
第一次与第二次握手完成意味着:A 能发送请求到 B,并且 B 能解析 A 的请求
第二次与第三次握手完成意味着:A 能解析 B 的请求,并且 B 能发送请求到 A
这样就保证了A 与 B 之间既能相互发送请求也能相互接收解析请求。同时避免了因为网络延迟产生的重复连接问题,比如 A 发送一次连接请求但网络延迟导致这次请求是在 A 重发连接请求并完成与 B 通信之后的,有三次握手的话,B 返回的建立请求 A 就不会理睬了。
短连接与长连接?
上图是一个短连接的过程演示,对于长连接,A 与 B 完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。另外,由于长连接的实现比较困难,需要要求长连接在没有数据通信时,定时发送数据包 (心跳),以维持连接状态,并且长连接对于服务器的压力也会很大,所以推送服务对于一般的开发者是非常难以实现的,这样的话就出现了很多不同的大型厂商提供的消息推送服务。
浏览器的功能是从服务器上取回你想要的资源,然后展示在浏览器窗口当中。资源通常是 HTML 文件,也可能是 PDF,图片,或者其他类型的内容。也可以显示其他类型的插件 (浏览器扩展)。例如显示 PDF 使用 PDF 浏览器插件。资源的位置通过用户提供的 URI(Uniform Resource Identifier) 来确定。
浏览器解释和展示 HTML 文件的方法,在 HTML 和 CSS 的标准中有详细介绍。这些标准由 Web 标准组织 W3C(World Wide Web Consortium) 维护。
从我们输入 URL 并按下回车键到看到网页结果之间发生了什么?换句话说,一张网页,要经历怎样的过程,才能抵达用户面前?下面来从一些细节上面尝试一下探寻里面的秘密。
前言:键盘与硬件中断
说到输入 URL,当然是从手敲键盘开始。对于键盘,生活中用到的最常见的键盘有两种:薄膜键盘、机械键盘。
键盘传输信号到操作系统后便会触发硬件中断处理程序。硬件中断是操作系统中提高系统效率、满足实时需求的非常重要的信号处理机制,它是一个异步信号,并提供相关中断的注册表(IDT)与请求线(IRQ)。键盘被按压时,将通过请求线将信号输入给操作系统,CPU 在当前指令结束之后,根据注册表与信号响应该中断并利用段寄存器装入中断程序入口地址。具体可参看操作系统与汇编相关书籍。
当然本文主要不是介绍硬件与操作系统中的细节,前言只是想说明,从输入 URL 到浏览器展现结果页面之间有太多底层相关的知识,怀着一颗敬畏的心并且在有限的篇幅中是无法详细阐述的,所以本文会将关注点放在在一个稍高的角度上来看,从浏览器替我们发送请求之后到看到页面显示完成这中间中发生了什么事情,比如 DNS 解析、浏览器渲染。
浏览器解析 URL
按下回车键之前
比如我按下一个‘b’键,会出现很多待选 URL 给我,第一个便是百度。那么其实是在浏览器接收到这个消息之后,会触发浏览器的自动完成机制,会在你之前访问过的搜索最匹配的相关 URL,会根据特定的算法显示出来供用户选择。
按下回车键之后
依据上述键盘触发原理,一个专用于回车键的电流回路通过不同的方式闭合了。然后触发硬件中断,随之操作系统内核去处理对应中断。省略其中的过程,最后交给了浏览器这样一个 “回车” 信号。那么浏览器(本文涉及到的浏览器版本都为 Chrome 61)会进行以下但不仅限于以下炫酷(乱七八糟)的步骤:
DNS 解析
不查 DNS,读取缓存
发送 DNS 查找请求
DNS 的查询方式是:按根域名 -> 顶级域名 -> 次级域名 -> 主机名这样的方式来查找的,对于某个 URL,如下所示
查询步骤为:
以 www.google.com 为例,下面是一整个 DNS 查询过程:
所以总的来说,DNS 的解析是一个逐步缩小范围的查找过程。
建立 HTTPS、TCP 连接
确定发送目标
拿到 IP 之后,还需要拿到那台服务器的 MAC 地址才行,在以太网协议中规定,同一局域网中的一台主机要和另一台主机进行直接通信,必须要知道目标主机的 MAC 地址。所以根据ARP(根据 IP 地址获取物理地址的一个 TCP/IP 协议)获取到 MAC 地址之后保存到本地 ARP 缓存之后与目标主机准备开始通信。具体细节参见维基百科 DHCH/ARP。
建立 TCP 连接
这样就保证了A 与 B 之间既能相互发送请求也能相互接收解析请求。同时避免了因为网络延迟产生的重复连接问题,比如 A 发送一次连接请求但网络延迟导致这次请求是在 A 重发连接请求并完成与 B 通信之后的,有三次握手的话,B 返回的建立请求 A 就不会理睬了。
上图是一个短连接的过程演示,对于长连接,A 与 B 完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。另外,由于长连接的实现比较困难,需要要求长连接在没有数据通信时,定时发送数据包 (心跳),以维持连接状态,并且长连接对于服务器的压力也会很大,所以推送服务对于一般的开发者是非常难以实现的,这样的话就出现了很多不同的大型厂商提供的消息推送服务。
进行 TLS 加密过程
服务端的处理
静态缓存、CDN
为了优化网站访问速度并减少服务器压力,通常将 html、js、css、文件这样的静态文件放在独立的缓存服务器或者部署在类似 Amazon CloudFront 的 CDN 云服务上,然后根据缓存过期配置确定本次访问是否会请求源服务器来更新缓存。
负载均衡
负载均衡具体实现有多种,有直接基于硬件的 F5,有操作系统传输层 (TCP) 上的 LVS,也有在应用层 (HTTP) 实现的反向代理(也叫七层代理),下面简单介绍一下最后者。
在请求发送到真正处理请求的服务器之前,还需要将请求路由到适合的服务器上,一个请求被负载均衡器拿到之后,需要做一些处理,比如压缩请求(在 nginx 中 gzip 压缩格式是默认配置在 nginx.conf 内的,所以默认开启,如果不对数据量要求特别精细的话,默认配置完全可以满足基本需求)、接收请求(接收完毕后才发给 Server,提高 Server 处理效率),然后根据预定的路由算法,将此次请求发送到某个后台服务器上。
其中需要提到的一点是反向代理,先回顾一下反向代理的原理: 正向代理是将自己要访问的资源告诉 Proxy,让 Proxy 帮你拿到数据返回给你,Proxy 服务于 Client,常用于翻墙和跨权限操作; 反向代理也是将自己要访问的资源告诉 Proxy,让 Proxy 帮你拿到数据返回给你,但是 Proxy 服务于 Server,它会将请求接受完毕之后发送给某一合适的 Server,这个时候 Client 是不知道是根据什么规则并且也不知道最后是哪一个 Server 服务于它的,所以叫反向代理,常用于负载均衡、安全控制.
服务器的处理
对于 HTTPD(HTTP Daemon) 在服务器上部署,最常见的 HTTPD 有 Linux 上常用的 Apache 和 Nginx。对于 Java 平台来说,Tomcat 是 Spring Boot 也会默认选用的 Servlet 容器实现,Tomcat 对于请求的处理如下:
浏览器的渲染
下面会以 Chrome 中使用的浏览器引擎 Webkit 为例,根据上图来简单介绍浏览器的渲染。具体解析、渲染会涉及到非常多的细节,请参考 HTML5 渲染规范和对应的页面 GPU 渲染实现。
HTML 解析
浏览器拿到具体的 HTML 文档之后,需要调用浏览器中使用的浏览器引擎中处理 HTML 的工具(HTML Parser)来将 HTML 文档解析成为DOM 树,将以便外部接口(JS)调用。
CSS 解析
页面渲染
解析完成后,浏览器引擎会通过 DOM 树和 CSS Rule 树来构造渲染树。渲染树的构建会产生 Layout,Layout 是定位坐标和大小,是否换行,各种 position, overflow, z-index 属性的集合,也就是对各个元素进行位置计算、样式计算之后的结果。
接下来,根据渲染树对页面进行渲染(可以理解为 “画” 元素)。
当然,将这个渲染的过程完成并显示到屏幕上会涉及到显卡的绘制,显存的修改,有兴趣的读者可以深入了解。
<iframe src="https://www.icloud.com/keynote/0Mu0DJnu0kyfoZwSZUmCYKSWQ?embed=true" width="640" height="500" frameborder="0" allowfullscreen="1" referrer="no-referrer"></iframe>参考
https://github.com/skyline75489/what-happens-when-zh_CN
http://achuan.me/2017/03/01/20170301how-browser-works/
https://zh.wikipedia.org/wiki/HTTP%E4%B8%A5%E6%A0%BC%E4%BC%A0%E8%BE%93%E5%AE%89%E5%85%A8
http://www.ruanyifeng.com/blog/2010/02/url_encoding.html
https://technet.microsoft.com/en-us/library/cc772774(v=ws.10).aspx
http://www.ruanyifeng.com/blog/2016/06/dns.html
jawil/blog#14
http://robertheaton.com/2014/03/27/how-does-https-actually-work/
共计:8575 个字
The text was updated successfully, but these errors were encountered: