内容
无论你是想要了解高性能Web应用还是优化现在的web应用,你都需要了解浏览器中的网络流程页面渲染过程 , JavaScript执行流程以及web安全理论 , 而这些功能是分散在浏览器的各个功能组件中的比较多,比较散。 所以 需要基于 浏览器的多进程架构 , 基于该架构就可以把分散的知识点串起来,组成一场网 ,从而让自己站在更高的维度去理解web应用
因此对于学习浏览器的多进程架构是很有必要的,之后的分析多是基于Chrome浏览器。 那为什么选择chrome ,而微软的edge以及国内大部分的主流浏览器都是基于Chromium二次开发而来的 。 Chrome是谷歌的官方发行版,特性和Chromium基本一样,只存在一些产品层面差异,再加上chrome是目前世界上使用率最高的浏览器,所以chrome最具有代表性 。
接下来开始看chrome的任务管理器的窗口 ,
任务管理器界面
和Windows任务管理器一样,chrome任务管理器也是用来展示运行中Chrome使用的进程信息 , 初中没看到chrome,启用了4个进程 ,但为什么是4个呢 ?
在解决这个问题之前,我们需要先来看一下进程的概念,容易把进程和线程的概念的混淆,从而影响后续其他概念的理解,所以在这里我们就先将这两个概念以及它们之间的关系 解释清楚。
进程和线程
不过在解释线程和进程之前,需要先讲讲解一下什么是并行处理 , 因为你一旦理解了行处理的概念之后,那么在理解进程和线程之间的关系就会变得轻松许多。
什么是并行处理
计算机中的并行处理就是同一时刻处理多个任务务 比如我们要计算下面这三个表达式的值,并显示出结果,
A = 1+2
B = 20/5
C = 7*8
在编写代码的时候,我们可以把这个过程拆分为4个任务 ,
任务1是计算:A = 1+2
任务2是计算:B = 20/5
任务3是计算:C = 7*8
任务4是计算:显示最后计算的结果
正常情况下程序可以用单线程来处理,也就是分4步,按照顺序分别执行这4个任务 ,那如果采用多线程会怎么样?我们只需要分两步,第1步使用,三个线程同时执行前三个任务,第2步再执行,第4个显示任务。 通过对比分析,你会发现用单线程执行需要4步,我用多线程只需要两步,因此使用并行处理能大大提升性能。
线程 VS 进程
多线程可以并行处理任务,但线程 是不能单独存在的,它是由进程来启动和管理的,那什么又是进程呢? 一个进程就是一个程序的运行实例,详细解释就是启动一个进程的时候,操作系统会为该程序创建一块内存,用来存放代码 ,运行中的数据和一个执行任务的主线程,这样我们把这样一整个运行环境叫做一个进程。
所以从图中可以看出线程是依附于进程的,而进程中使用多线程行处理难提升运算效率 。
总结来说 ,进程和线程之间有以下4点 ,
- 进程中的任意一现成执行错误都会导致整个进程的崩溃,
比如上述式子, 一旦把分母改为零后线程会执行出错,
这样会导致整个进程的崩溃,另外两个的执行结果也就没有了。
-
线程之间共享进程的数据
线程之间共享进程中的数据示意图
从上图可以看出线程1线程2线程3分别把执行的结果写入abc中,
然后线程2要继续从abc 中读取数据,用来显示执行结果。
3 . 当一个进程关闭之后,操作系统会回收进程所占用的内存
一个进程退出时,操作系统会回收该进程所申请的所有资源,
即使其中任意线程因为操作不到导致内存泄漏到导致内存泄漏 ,
当进程推出时,这些内存也会被正确回收。
比如之前的IE浏览器支持很多插件啊,
这些插件很容易导致内存泄漏,意味着只要浏览器开着,
内存占用就会可能越来越高,但是当关闭浏览器进程时,这些内存就会被系统回收。
- 进程之间的内容相互隔离
进程隔离是为保护操作系统中进程互不干扰的技术,
每一个进程只能访问自己占有的数据 ,
也就避免出现进程A写入数据到进程B的情况,
正是因为进程之间的数据是严格隔离的,
所以一个进程如果崩溃了或者挂起了,
是不会影响到其他进程的 。
如果进程之间需要进行数据的通信,
这时候就需要使用用于进程间通信(IPC)的机制了。
单进程浏览器时代
在了解了进程和线程之后,我们再来一起看一下单进程浏览器的架构 ,顾名思义,当进程浏览器是指浏览器所有的功能模块都同时运行在同一个进程里面 , 这些模块包含了网络插件,JavaScript运行环境渲染引擎和页面等 , 其实早在2007年之前,市面上浏览器都是单进程的 , 单进程的架构如下图所示 ,
- 问题:不稳定
手机浏览器需要借助于插件,还是先注入web视频web游戏等各种强大的功能,
但是插件是最容易出问题的模块,并且还运行在浏览器进程之中,所以一个插件的意外崩溃,
会引起整个浏览器的崩溃。
除了插件之外,渲染引擎也是不不稳定的,
通常一些复杂的JavaScript代码就有可能引起渲染引擎模块的崩溃,
和插件一样, 渲染引擎的崩溃也会导致整个浏览器的崩溃。
- 问题:不流畅
比如我们让一个无限循环脚本进行在 一个单进程浏览器页面里 ,
那会发生什么事情呢 ? 因为这个脚本是无限循环的,所以当其执行时,
它会独占整个线程 ,这样导致其他运行在该线程中的模块就没有机会被执行。
因为浏览器中所有页面都运行在该线程中 ,所以这些页面都没有机会去执行任务,
那就会导致整个流程去失响应,变卡顿。(这边的内容会涉及到页面,事件的循环系统 )
- 问题:不安全
这里依然可以从插件和页面脚本两个方面来解释该原因 ,
插线可以使用c/c++等代码来编写,通过插件可以获取到操作系统的任意资源,
当你在页面运行一个插件时,也就意味着这个插件能完全操作你的电脑 ,
如果是一个恶意插件,那么它就可以释放病毒,窃取你的账号密码,引发安全性问题 。
至于页面脚本,它可以通过浏览器的漏洞来获取系统权限,
这些脚本获取系统权限之后,也可以对你的电脑做出一些恶意的事情,同样也会引发安全问题。
以上这些就是当时浏览器的特点,不稳定,不流畅也不安全。
多进程浏览器时代
早期多进程架构
早期Chrome进程架构图上图是2008年chrome发布时的进程架构 , 从上图可以看出 ,chrome的页面是运行在单独的渲染进程中的同时,页面里的插件也是运行在单独的插件进程中的 ,而进程之间是通过IPC 机制进行通信 (如图中虚线部分)
- 解决不稳定问题
由于进程是相互隔离的,所以当一个页面或者插件崩溃时影响到了,
仅仅是当前的页面进程或者插件进程并不会影响到浏览器和其他页面 ,
这样就完美解决了 ,页面或插件的崩溃会导致整个浏览器崩溃,也就是不稳定的问题。
- 解决不流畅问题
同样 ,JavaScript也是运行在渲染进程中的,所以即使JavaScript阻塞了,
渲染进程影响到的也只是当前的渲染页面,而并不会影响浏览器或其他页面,
因为其他页面的脚本是运行在他们自己的渲染进程中的,
所以当我们在Chrome运行上面那个死循环的时候,没有响应的仅仅是当前的页面。
对于内存泄露的解决方法那就更简单了,因为当关闭一个页面时,
整个渲染进程也会被关闭之后该进程所占用的所有内存都会被系统回收,
这样就轻松解决了浏览器页面的内存泄露问题。
- 解决不安全问题
采用多进程架构的额外好处就是可以使用安全沙箱 ,
你可以把沙箱看做成操作系统给进程上了一把锁, 沙箱里面的程序可以运行,
但是不能在你的硬盘上写入任何数据,也不能在敏感位置读取任何数据 ,
例如你的文档和桌面 ,Chrome把插件进程和渲染进程锁在沙箱里面,
这样即使在渲染进程或者插件进程里面执行的恶意程序,也无法突破沙箱,去获取系统权限 。
目前多进程架构
最新的Chrome进程架构图从图中可以看出最新的chrome浏览器,包括一个浏览器主进程,一个GPU主进程,一个网络进程 ,多个渲染进程和多个插件进程。
主要功能:
1) 浏览器进程:
主要负责界面显示、用户交互 、子进程管理、同时提供存储等功能
2) 渲染进程
核心任务是讲html CSS和JavaScript转换为用户可以与之交互的网页排版,
引擎blink和JavaScript配件v8都是运行在该进程中 ,默认情况下,
chrome会为每个tab标签创建一个渲染进程。注意安全,考虑渲染进程,都是运行在箱模式下。
3) GPU进程
其实chrome刚开始发布的时候是没有GPU进程的,而GPU使用初衷是为了实现3D CSS的效果 ,
只是随后网页和Chrome UI界面都采用GPU来绘制 ,这样使得GPU成为浏览器普遍的需求,
最后chrome在一起多进程架构上也引入了GPU进程。
4) 网络进程
主要负责页面的网络资源加载 ,之前是作为一个模块运行在浏览器进程里面的 ,
直至最近才独立出来成为一个单独的进程。
5) 插件进程
主要上负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,
以保证插件进程崩溃,不会对浏览器和页面造成影响,
所以这就是为什么 只开了一个界面,但为什么会有4个进程 ?
因为打开一个页面,
至少需要一个网络进程,一个浏览器进程,一个GPU进程,以及一个渲染进程,共4个 ,
如果打开了页面有运行插件的话,还需要再加上一个插件进程。
但凡事都有两面性,虽然多进程模型提高了浏览器的稳定性,流畅性和安全性,
但同样不可避免的带来的一些问题,
1. 更高的资源占用
因为每个进程都会包含公共基础结构的副本 ,
这就意味着浏览器会消耗更多的内存资源
2. 更复杂的体系架构
浏览器各模块之间耦合性高扩展性差等问题,
会导致现在的架构已经很难适应新的需求了 。
未来面向服务的架构
为了解决这些问题,在2016年Chrome官方团队使用面向服务的架构 ,(services oriented architecture,SOA) 的思想设计了新的Chrome架构,也就是说Chrome整体架构会朝向现代操作系统所采用的面向服务的架构方向发展, 原来的各种模块都会被重构成独立的服务 ,每个服务都可以在独立的进程中运行,访问服务必须使用定义好的接口,通过IPC来通信 ,从而构建一个更内聚,松耦合,易于维护和扩展的系统 , 更好实现chrome简单稳定,高速安全的目标 。
Chrome最终要把uI数据库文件设备网络的模块重构为 基础服务,类似操作系统底层服务。
Chrome面向服务的架构进程模型图
目前chrome正处在老的架构向服务化架构过渡阶段,这将是一个漫长的迭代过程, Chrome正在逐步构建chrome基础服务 (Chrome Foundation Service),如果你能认为chrome是便携式操作系统那么chrome ,基础服务便可以视为该操作系统的基础系统服务层。
公司chrome还提供灵活的弹性构架,在强大性能设备上会以多进程的方式运行技术服务,但是如果在资源受限的设备上 ,可能会将很多服务整合到一个进程中,从而节省内存占用。
在资源不足的设备上将服务合并到浏览器进程中
小结
本文主要是从chrome进程架构的视角分析了浏览器的进化史 , 最初的浏览器都是当进程的,他们不稳定不流畅且不安全之后出现的chrome ,创造性的引入了多进程架构 ,并解决了这些遗留问题 , 随后chrome视图应用到更多业务场景,如移动设备VR视频等,为了支持这些场景chrome的架构体系变得越来越复杂 ,这种架构的复杂性倒逼chrome开发团队必须进行架构的重构 , 最终Chrome全团队选择了面向服务架构形式 ,这也是Chrome团队现阶段的一个主要任务 。
总体来说chrome是以一个 非常快速的速度在进化,越来越多的业务和应用都逐渐转至浏览器来开发,所以,要努力。
网友评论