【浏览器工作原理与实践】1. 宏观视角下的浏览器 - chrome 多进程架构

进程和线程是什么

并行处理:计算机中的并行处理就是同一时刻处理多个任务,好处:提升性能。

  • 线程:线程是不能单独存在的,它由进程来启动和管理。
  • 进程:就是一个程序的运行实例。详细解释就是,启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。
进程线程处理
进程线程处理

线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率。

进程和线程关系

  • 进程中的任意一线程执行出错,都会导致整个进程的崩溃。
  • 线程之间共享进程中的数据。
  • 当一个进程关闭之后,操作系统会回收进程所占用的内存。
  • 进程之间的内容相互隔离。进程崩溃或挂起不影响其他进程,进程间进行数据通信,需要使用进程间通信(IPC)的机制
线程之间共享进程中的数据示意图
线程之间共享进程中的数据示意图

单进程浏览器时代

单进程浏览器架构示意图
单进程浏览器架构示意图

单进程浏览器是指浏览器的所有功能模块都是运行在同一个进程里,这些模块包含了网络、插件、JavaScript 运行环境、渲染引擎和页面等。其实早在 2007 年之前,市面上浏览器都是单进程的。

如此多的功能模块运行在一个进程里,是导致单进程浏览器不稳定不流畅不安全的一个主要因素。

  • 不稳定:由于是单线程,在运行过程中某一模块的崩溃或阻塞都会导致整个浏览器的崩溃。
  • 不流畅:同一时刻只能有一个模块可以执行,如果有一个无限循环的脚本,这个脚本会独占整个线程,导致页面没有机会执行任务,进而导致整个浏览器卡顿或失去相应。运行一个复杂点的页面再关闭页面,会存在内存不能完全回收的情况,这样导致的问题是使用时间越长,内存占用越高,造成内存泄露问题,也会导致浏览器变慢。
  • 不安全:插件,可以使用 C/C++ 等代码编写,通过插件可以获取到操作系统的任意资源。页面脚本,它可以通过浏览器的漏洞来获取系统权限,获取权限之后可以对电脑进行操作。两者都会引发安全问题。

早期多进程架构

2008 年 Chrome 发布时的进程架构:

早期 Chrome 进程架构图
早期 Chrome 进程架构图

  • 解决不稳定的问题:由于进程是相互隔离的,所以当一个页面或者插件崩溃时,影响到的仅仅是当前的页面进程或者插件进程,并不会影响到浏览器和其他页面。
  • 解决不流畅的问题:每个页面的脚本是运行在它们自己的渲染进程中的,因此即使 JavaScript 阻塞了渲染经常,也只会影响到当前的渲染页面。
  • 解决内存泄露问题:关闭一个页面时,整个渲染进程也会被关闭,之后该进程所占用的内存都会被系统回收。
  • 解决安全问题:使用安全沙箱,Chrome 把插件进程和渲染进程锁在沙箱里面,这样即使在渲染进程或者插件进程里面执行了恶意程序,恶意程序也无法突破沙箱去获取系统权限。

目前多进程架构

最新的 Chrome 进程架构图
最新的 Chrome 进程架构图

从图中可以看出,最新的 Chrome 浏览器包括:

  • 1 个浏览器(Browser)主进程。主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  • 1 个网络(NetWork)进程。主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。
  • 1 个 GPU 进程。其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。
  • 多个渲染进程。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • 多个插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

打开 1 个页面至少需要 1 个网络进程、1 个浏览器进程、1 个 GPU 进程以及 1 个渲染进程,共 4 个;如果打开的页面有运行插件的话,还需要再加上 1 个插件进程。

一些缺点:

  • 更高的资源占用。因为每个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),这就意味着浏览器会消耗更多的内存资源。
  • 更复杂的体系架构。浏览器各模块之间耦合性高、扩展性差等问题,会导致现在的架构已经很难适应新的需求了。

未来面向服务的架构

为了解决这些问题,在 2016 年,Chrome 官方团队使用 “面向服务的架构”(Services Oriented Architecture,简称 SOA)的思想设计了新的 Chrome 架构。也就是说 Chrome 整体架构会朝向现代操作系统所采用的 “面向服务的架构” 方向发展,原来的各种模块会被重构成独立的服务(Service),每个服务(Service)都可以在独立的进程中运行,访问服务(Service)必须使用定义好的接口,通过 IPC 来通信,从而构建一个更内聚、松耦合、易于维护和扩展的系统,更好实现 Chrome 简单、稳定、高速、安全的目标。

Chrome“面向服务的架构”进程模型图
Chrome “面向服务的架构” 进程模型图

目前 Chrome 正处在老的架构向服务化架构过渡阶段,这将是一个漫长的迭代过程。

Chrome 正在逐步构建 Chrome 基础服务(Chrome Foundation Service),如果你认为 Chrome 是 “便携式操作系统”,那么 Chrome 基础服务便可以被视为该操作系统的 “基础” 系统服务层。

同时 Chrome 还提供灵活的弹性架构,在强大性能设备上会以多进程的方式运行基础服务,但是如果在资源受限的设备上(如下图),Chrome 会将很多服务整合到一个进程中,从而节省内存占用。

服务合并到浏览器进程
服务合并到浏览器进程