多进程架构

假如我们去开发一个浏览器,它的架构

  • 可以是一个单进程多线程的应用程序
  • 也可以是一个使用IPC通信的多进程应用程序。

不同的浏览器使用不同的架构,下面主要以Chrome为例,介绍浏览器的多进程架构。在Chrome中,主要的进程有4个:

  • 浏览器进程 (Browser Process):负责浏览器的TAB的前进、后退、地址栏、书签栏的工作和处理浏览器的一些不可见的底层操作,比如网络请求和文件访问。
  • 渲染进程 (Renderer Process):负责一个Tab内的显示相关的工作,也称渲染引擎。
  • 插件进程 (Plugin Process):负责控制网页使用到的插件
  • GPU进程 (GPU Process):负责处理整个应用程序的GPU任务

工作原理

首先,当我们是要浏览一个网页,我们会在浏览器的地址栏里输入URL,这个时候Browser Process会向这个URL发送请求,获取这个URL的HTML内容,然后将HTML交给Renderer Process

Renderer Process解析HTML内容,解析遇到需要请求网络的资源又返回来交给Browser Process进行加载,同时通知Browser Process,需要Plugin Process加载插件资源,执行插件代码。

解析完成后,Renderer Process计算得到图像帧,并将这些图像帧交给GPU Process,GPU Process将其转化为图像显示屏幕。

多进程架构的好处

更高的容错性

  • 当今WEB应用中,HTML,JavaScript和CSS日益复杂,这些跑在渲染引擎的代码,频繁的出现BUG,而有些BUG会直接导致渲染引擎崩溃
  • 多进程架构使得每一个渲染引擎运行在各自的进程中,相互之间不受影响,也就是说,当其中一个页面崩溃挂掉之后,其他页面还可以正常的运行不收影响。

更高的安全性和沙盒性(sanboxing)

  • 渲染引擎会经常性的在网络上遇到不可信、甚至是恶意的代码,它们会利用这些漏洞在你的电脑上安装恶意的软件
  • 针对这一问题,浏览器对不同进程限制了不同的权限,并为其提供沙盒运行环境,使其更安全更可靠

更高的响应速度。

  • 在单进程的架构中,各个任务相互竞争抢夺CPU资源,使得浏览器响应速度变慢,而多进程架构正好规避了这一缺点

虽然浏览器的多进程模型提升了浏览器的稳定性、流畅性和安全性,但是也带来了一些其它的问题:例如 更高的资源占用和更复杂的体系结构

浏览器的进程模式

为了节省内存,Chrome提供了四种进程模式(Process Models),不同的进程模式会对 tab 进程做不同的处理。

  • Process-per-site-instance (default) - 同一个 site-instance 使用一个进程
  • Process-per-site - 同一个 site 使用一个进程
  • Process-per-tab - 每个 tab 使用一个进程
  • Single process - 所有 tab 共用一个进程

site 和 site-instance 的定义

  • site: 指的是相同的 registered domain name(如: google.com ,bbc.co.uk)和scheme (如:https://)

    • 比如a.baidu.com和b.baidu.com就可以理解为同一个 site(注意这里要和 Same-origin policy 区分开来,同源策略还涉及到子域名和端口)。
  • site-instance: 指的是一组 connected pages from the same site,这里 connected 的定义是 can obtain references to each other in script code

  • 满足下面两情况并且打开的新页面和旧页面属于上面定义的同一个 site,就属于同一个 site-instance

    • 用户通过 <a target="_blank"> 这种方式点击打开的新页面
    • JS代码打开的新页面,比如 window.open

解释四个进程模式

Single process

  • 顾名思义,单进程模式,所有tab都会使用同一个进程。

Process-per-tab

  • 顾名思义,每打开一个tab,会新建一个进程

Process-per-site

  • 当打开 a.baidu.com 页面,在打开 b.baidu.com 的页面,这两个页面的tab使用的是共一个进程,因为这两个页面的site相同,而如此一来,如果其中一个tab崩溃了,而另一个tab也会崩溃。

Process-per-site-instance

  • 是最重要的,因为这个是 Chrome 默认使用的模式,也就是几乎所有的用户都在用的模式
  • 当打开一个 tab 访问 a.baidu.com ,然后再打开一个 tab 访问 b.baidu.com,这两个 tab 会使用两个进程
  • 而如果在 a.baidu.com 中,通过JS代码打开了 b.baidu.com 页面,这两个 tab 会使用同一个进程

默认模式选择

那么为什么浏览器使用Process-per-site-instance作为默认的进程模式呢?

  • 兼容了性能与易用性,是一个比较中庸通用的模式。

  • 相较于 Process-per-tab,能够少开很多进程,就意味着更少的内存占用

  • 相较于 Process-per-site,能够更好的隔离相同域名下毫无关联的 tab,更加安全