• 极客时间之浏览器工作原理与实践笔记


    Chapter 1 宏观视角下的浏览器

    1. 仅仅打开了1个页面,为什么有4个进程?

    进程和线程的关系:

    1. 进程中的任意一个线程出错,都会导致整个进程的崩溃
    2. 线程之间可以共享进程中的数据
    3. 当一个进程关闭之后,os会回收进程所申请的全部资源
    4. 进程之间的内容相互隔离

    单进程浏览器时代

    单进程浏览器,顾名思义就是所有的功能、模块都运行在一个进程里,在2007年以前,市面上所有的浏览器都是单进程的。毫无疑问肯定很不好使。它会出现不稳定、不流畅、不安全等状况。

    • 不稳定
      我们知道,进程中任意一个线程出错,都会导致整个进程的崩溃。所以如果任意一个插件或者渲染引擎出了问题,就会导致整个浏览器崩溃掉。
    • 不流畅
      单进程导致同一时刻只有一个模块可以执行,如果碰巧你这个模块写成了死循环,那后果就可想而知了。
      除了这个原因外,页面的内存泄漏也是单进程变慢的一个重要原因。通常浏览器的内核都是非常复杂的,运行一个复杂点的页面再关闭页面,会存在内存不能完全回收的情况,这样导致的问题是使用时间越长,内存占用越高,浏览器会变得越慢。

    多进程浏览器时代

    早期

    早期Chrome进程架构图

    • 解决不稳定:
      进程之间相互隔离,当一个页面或者一个插件崩溃时,影响的只是他自己,并不会影响到浏览器和其他页面
    • 解决不流畅:
      JavaScript 也是运行在渲染进程中的,所以即使 JavaScript 阻塞了渲染进程,影响到的也只是当前的渲染页面,而并不会影响浏览器和其他页面,因为其他页面的脚本是运行在它们自己的渲染进程中的。所以当我们再在 Chrome 中运行上面那个死循环的脚本时,没有响应的仅仅是当前的页面。
      而对于内存泄漏:当关闭一个页面时,整个渲染进程也会被关闭,之后该进程所占用的内存都会被系统回收,这样就轻松解决了浏览器页面的内存泄漏问题。
    • 解决不安全:
      采用多进程架构的额外好处是可以使用安全沙箱,你可以把沙箱看成是操作系统给进程上了一把锁,沙箱里面的程序可以运行,但是不能在你的硬盘上写入任何数据,也不能在敏感位置读取任何数据,例如你的文档和桌面。Chrome 把插件进程和渲染进程锁在沙箱里面,这样即使在渲染进程或者插件进程里面执行了恶意程序,恶意程序也无法突破沙箱去获取系统权限。

    目前

    最新的 Chrome 进程架构图
    分析下进程的功能

    • 浏览器主进程:主要负责页面显示、用户交互、子进程管理、存储
    • 渲染进程:将三件套转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
    • GPU进程:绘制网页、chrome的ui界面
    • 网络进程:负责页面的网络资源加载
    • 插件进程:负责插件的运行,因为插件容易崩溃,所以用插件进程来隔离插件,保证插件崩溃了也不会影响页面和浏览器。
      那么我们现在知道了,仅仅打开了 1 个页面,为什么有 4 个进程?因为打开 1 个页面至少需要 1 个网络进程、1 个浏览器进程、1 个 GPU 进程以及 1 个渲染进程,共 4 个;如果打开的页面有运行插件的话,还需要再加上 1 个插件进程。
      but 多进程浏览器就没有缺点吗?当然不是了,它的问题在于,占用了更高的资源,体系架构也更复杂了。

    未来面向服务的架构

    为了解决这两个问题,2016年,chrome官方团队使用SOA(面向服务的架构)设计了新的架构Chrome“面向服务的架构”进程模型图
    在资源不足的设备上,将服务合并到浏览器进程中
    在如今多进程浏览器时代下,偶尔也会出现单个页面卡死最终崩溃导致所有页面崩溃的情况,这是因为:
    通常情况下是一个页面使用一个进程,但是如果几个页面符合同一站点,那么他们将被分配到一个渲染进程里面去。所以,这种情况下,一个页面崩溃了,会导致同一站点的页面同时崩溃,因为他们使用了同一个渲染进程。那为什么要让他们跑在一个进程里面呢?因为在一个渲染进程里面,他们就会共享JS的执行环境,也就是说A页面可以直接在B页面中执行脚本。因为是同一家的站点,所以是有这个需求的。

    2. TCP协议:如何保证页面文件能被完整送达浏览器?

    首先要了解的:互联网中的数据是通过数据包来传输的。如果发送的数据很大,那么该数据就会被拆分为很多小数据包来传输。比如你现在听的音频数据,是拆分成一个个小的数据包来传输的,并不是一个大的文件一次传输过来的。

    2.1 IP:把数据包送达目的主机

    IP就是Internet Protocol – 网络协议
    计算机的地址就称为 IP 地址,访问任何网站实际上只是你的计算机向另外一台计算机请求信息。
    IP 头是 IP 数据包开头的信息,包含 IP 版本、源 IP 地址、目标 IP 地址、生存时间等信息。简化的 IP 网络三层传输模型

    2.2 UDP:把数据包送达应用程序

    IP是非常底层的协议,它只负责把数据包传送到对方的电脑上,具体要传给哪个程序是由UDP(User Datagram Protocol)(用户数据包协议决定的)

    UDP 中一个最重要的信息是端口号,端口号其实就是一个数字,每个想访问网络的程序都需要绑定一个端口号。通过端口号 UDP 就能把指定的数据包发送给指定的程序了,所以IP 通过 IP 地址信息把数据包发送给指定的电脑,而 UDP 通过端口号把数据包分发给正确的程序。和 IP 头一样,端口号会被装进 UDP 头里面,UDP 头再和原始数据包合并组成新的 UDP 数据包。UDP 头中除了目的端口,还有源端口号等信息。简化的 UDP 网络四层传输模型
    在使用 UDP 发送数据时,有各种因素会导致数据包出错,虽然 UDP 可以校验数据是否正确,但是对于错误的数据包,UDP 并不提供重发机制,只是丢弃当前的包,而且 UDP 在发送之后也无法知道是否能达到目的地。

    虽说UDP 不能保证数据可靠性,但是传输速度却非常快,所以 UDP 会应用在一些关注速度、但不那么严格要求数据完整性的领域,如在线视频、互动游戏等。

    2.3 TCP:把数据完整地送达应用程序

    对于浏览器请求,或者邮件这类要求数据传输可靠性的应用,如果使用 UDP 来传输会存在两个问题:

    • 数据包在传输过程中容易丢失;
    • 大文件会被拆分成很多小的数据包来传输,这些小的数据包会经过不同的路由,并在不同的时间到达接收端,而 UDP 协议并不知道如何组装这些数据包,从而把这些数据包还原成完整的文件。

    为了解决这两个问题,我们引入了 TCP (Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

    • 对于数据包丢失的情况,TCP 提供重传机制;

    • TCP 引入了数据包排序机制,用来保证把乱序的数据包组合成一个完整的文件。
      简化的 TCP 网络四层传输模型
      一个 TCP 连接的生命周期

    • 三次握手建立连接:
      这个阶段是通过“三次握手”来建立客户端和服务器之间的连接。

      • TCP 提供面向连接的通信传输
      • 面向连接是指在数据通信开始之前先做好两端之间的准备工作。
      • 三次握手是指在建立一个TCP连接时,客户端和服务器总共要发送三个数据包以确认连接的建立。
    • 传输数据:
      在此阶段,接收端需要对每个数据包进行确认操作,在接收到数据包后,要向发送端发送确认数据包。

      所以如果发送端发送了一个数据包,但是却没有收到回复,那么代表这个数据包丢失了。然后就会触发发送端的重发机制。

      同样,一个大的文件在传输过程中会被拆分成很多小的数据包,这些数据包到达接收端后,接收端会按照 TCP 头中的序号为其排序,从而保证组成完整的数据。

    • 四次挥手断开连接:四次挥手

    • 第一次挥手:客户端发送FIN=M,用来关闭客户端到服务器端的数据传送,然后客户端就会进入FIN_WAIT_1状态,意思就是说,我没有数据要发了,但是你如果要发数据的话,还可以发给我,不用急着关闭我们之间的连接
    • 第二次挥手:服务器端收到FIN=M后,发送ack=M+1,告诉客户端,我知道啦,但是,我还没准备好现在就关掉连接,请你继续等待我的消息。然后客户端就进入了FIN_WAIT_2状态,继续等待服务器端
    • 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。然后服务器端进入LAST_ACK状态。
    • 第四次挥手:服务器端收到了FIN=N报文,知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手

    TCP 为了保证数据传输的可靠性,牺牲了数据包的传输速度,因为“三次握手”和“数据包校验机制”等把传输过程中的数据包的数量提高了一倍。

    3. HTTP请求流程:为什么很多站点第二次打开速度会很快?

    HTTP是一种允许浏览器向服务器获取资源的协议,是WEB的基础。
    那么现在以http://time.geekbang.org/index.html为例,来探讨一下浏览器发起HTTP请求的流程吧

    浏览器端发起 HTTP 请求流程

    1.构建请求

    浏览器会先构建请求行信息,构建好后,浏览器准备发起网络请求

    GET /index.html HTTP1.1
    
    • 1

    2.查找缓存

    在真正发起请求之前,浏览器会先找找浏览器缓存(是指在本地保存资源副本,以供下次请求直接使用的技术)里有没有这个文件。

    • 如果找到了,拦截请求,直接返回这个资源的副本
    • 没找到,进入网络请求。

    3. 准备 IP 地址和端口

    • 了解HTTP和TCP的关系
      • 浏览器使用HTTP协议作为应用层协议,用来封装请求的文本信息
      • 使用TCP/IP作为传输层协议,将文本信息发送到网络上。
      • 所以,HTTP 的内容是通过 TCP 的传输数据阶段来实现的

    TCP 和 HTTP 的关系示意图
    所以我们知道了,HTTP网络请求的第一步是建立TCP连接。建立TCP连接需要有IP地址和端口号,IP地址和端口号我们有吗?我们知道我们现在有一个URL地址http://time.geekbang.org/index.html,那么从这个URL地址可以获得IP地址和端口号吗?

    • 拿到IP
      我们可以看到这个url地址的域名是time.geekbang.org。那么想要从域名获得IP地址,就要用到DNS(Domain Name System 域名系统)
      所以,HTTP网络请求的第一步,浏览器会请求DNS返回域名对应的IP。
      当然浏览器还提供了DNS 数据缓存服务,如果某个域名已经解析过了,那么浏览器会缓存解析的结果,以供下次查询时直接使用,这样也会减少一次网络请求。这样我们就拿到IP地址了
    • 拿到端口号
      通常情况下,如果 URL 没有特别指明端口号,那么 HTTP 协议默认是 80 端口。

    4. 等待TCP队列

    现在IP地址和端口号都已经拿到了,按理说已经可以开始建立TCP连接了,但是因为Chrome同一域名最多只能建立6个TCP连接,,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。,如果当前请求数量少于 6,会直接进入下一步,建立 TCP 连接。

    5. 建立 TCP 连接

    排队等待结束之后,终于可以和服务器握手了,在 HTTP 工作开始之前,浏览器通过 TCP 与服务器建立连接

    6. 发送 HTTP 请求

    建立TCP连接后,浏览器就可以和服务器进行通信了。
    HTTP 请求数据格式

    • 首先浏览器会向服务器发送请求行,它包括了请求方法、请求 URI(Uniform Resource Identifier)和 HTTP 版本协议。
      发送请求行,就是告诉服务器浏览器需要什么资源,最常用的请求方法是Get。比如,直接在浏览器地址栏键入极客时间的域名(time.geekbang.org),这就是告诉服务器要 Get 它的首页资源。
    • 如果要发送一些数据给服务器,就要用到POST请求,要发送的数据就放在请求体里。
    • 在浏览器发送请求行命令之后,还要以请求头形式发送其他一些信息,把浏览器的一些基础信息告诉服务器。比如包含了浏览器所使用的操作系统、浏览器内核等信息,以及当前请求的域名信息、浏览器端的 Cookie 信息,等等。

    服务器端处理 HTTP 请求流程

    请求送到了,接下来就轮到服务器端来处理请求信息了。

    1. 返回请求

    我们在命令行里输入
    curl -i url
    在这里插入图片描述

    2. 断开连接

    通常情况下,一旦服务器向客户端返回了请求数据,它就要关闭 TCP 连接。不过如果浏览器或者服务器在其头信息中加入了:Connection:kepp-alive,那么 TCP 连接在发送后将仍然保持打开状态,这样浏览器就可以继续通过同一个 TCP 连接发送请求。保持 TCP 连接可以省去下次请求时需要建立连接的时间,提升资源加载速度

    3.重定向

    当你在浏览器中打开 geekbang.org 后,你会发现最终打开的页面地址是 https://www.geekbang.org。
    这两个 URL 之所以不一样,是因为涉及到了一个重定向操作。跟前面一样,我们依然可以使用 curl 来查看下请求 geekbang.org 会返回什么内容。请添加图片描述

    问题汇总

    1. 为什么很多站点第二次打开速度会很快?
      第一次加载页面过程中,缓存了一些耗时的数据。如DNS缓存和页面资源缓存请添加图片描述
  • 相关阅读:
    java计算机毕业设计客服管理系统源码+mysql数据库+系统+lw文档+部署
    Linux学习笔记(10)----静态库与共享库
    什么是Scrum?如何实施Scrum(敏捷开发)以及敏捷工具
    Spark 内存管理堆内和堆外内存规划_大数据培训
    【COMP329 LEC3】
    Thanos Receiver
    使用AVX2指令集加速推荐系统MMR层余弦相似度计算
    CAUSE: ORA-15018: diskgroup cannot be created
    文件下载Blob
    【OFDM通信】基于深度学习的OFDM系统信号检测附matlab代码
  • 原文地址:https://blog.csdn.net/qq_51246916/article/details/125399136