您的位置:首页 > 运维架构 > 网站架构

Chromium多进程架构

2014-01-11 20:50 357 查看
本文描述Chromium的高层架构

问题

建造一个永远不会奔溃或挂起的渲染引擎几乎是不可能的。也基本不可能建造一个绝对安全的渲染引擎。
在某种程度上,当前的浏览器(本文发表于2008年)就像过去单用户,多任务协作的操作系统。这种操作系统中的一个应用错误可能使整个系统奔溃,在现代浏览器中,一个错误网页也会导致类似的行为。一个浏览器或插件错误就足于拖累整个浏览器和其它正在运行的tabs。

在现代操作系统中,应用程序被放入彼此独立,相互分离的进程中运行,这使得操作系统比以前健壮多了。一个应用程序的奔溃通常不会再影响到其它应用程序和系统完整性,而且严格限制一个用户对另一个用户的数据的访问。

总体架构

我们为每个浏览器tabs创建一个独立的进程,以使整个应用程序不受渲染引擎bugs和故障的影响。我们也限制每一个渲染进程对其它渲染进程和系统其余部分的访问。在某种程度上,这给网页浏览带来了好处,即内存保护和操作系统访问控制。

主进程运行UI,管理tab和插件进程,我们称之为“browser process" or "browser"。同理,与tab相关的进程被称为“render processes”或“renderers”。renderers 使用WebKit开源的排版引擎解释HTML,并对其进行排版。



管理渲染进程

每一个渲染进程有一个全局的RenderProcess对象,它管理者与父browser process的通信,并维护进程的全局状态。browser为每个渲染进程维护着一个RenderProcessHost,它为渲染进程管理browser状态和通信。the browser and renderers通过IPC(Chromium's
IPC system)进行通信。

管理视图(views)

每个渲染进程有一到多个RenderView对象,它们由RenderProcess对象管理,与内容页面相对应。对应的RenderProcessHost为渲染进程中的每一个view维护着一个RenderViewHost。每一个view被给予一个view ID,用于在同一渲染进程区别多个views。这些ID在一个渲染进程中是唯一的,在browser中就不一定了,所以标识一个view需要一个RenderProcessHost和一个view
ID。browser与特定内容页面的通信是通过RenderViewHost对象完成的,RenderViewHost对象知道如何通过RenderProcessHost发送消息到RenderProcess,继而发送到RenderView。

组件和接口(Components and interfaces)

渲染进程中:

RenderProcess处理与位于browser中对应的RenderProcessHost的IPC。每一个渲染进程只有一个RenderProcess。
RenderView对象与位于browser中对应的RenderViewHost(通过RenderProcess),还有我们的WebKit嵌入层通信。该对象代表一个网页的内容。

在browser进程中:

The browser对象代表一个顶层浏览器窗口
RenderProcessHost对象代表单个 browser <----> render IPC 连接的浏览器端。每一个渲染进程有一个RenderProcessHost。
RenderViewHost对象封装了与远程RenderView的通信,RenderWidgetHost为位于浏览器进程中的RenderWidget处理输入和绘制。

共享渲染进程(Sharing the render process)

通常,每个新的window和tab都是在新进程中打开的。The browser将产生一个新的进程并通知它创建一个RenderView。有时候需要或想要在几个tabs or windows之间共享渲染进程。一个web应用打开一个新窗口并期望与之同步通信,例如在JavaScript中使用window.open。在这个例子,当我们创建一个新窗口或tab时,我们需要需要重用打开原始窗口的进程。如果总的进程数量太大,或已经有一个浏览那个域名的进程打开时,我们也有把新的tabs分配给现有进程的策略。这些策略如Process
Models所述。

奔溃检测和渲染进程错误(Detecting crashed or misbehaving renders)

每一个连接到browser进程的IPC监测着进程句柄。如果这些句柄出现异常,就表示渲染进程已经奔溃,相应的tab也会被通知到。目前,我们通过显示一个“sad tab"屏幕通知用户渲染进程已经奔溃。可以通过按下reload button或开始一个新的浏览来重新加载网页。当这样做时,我们会发现没有对应的进程,就会创建一个新的。我们还可以宿主操作系统的内置权限来限制它对文件系统的访问。
除了限制渲染进程对网络和文件系统的访问,我们还能够限制它对用户显示相关对象的访问。我们在一个用户不可见的独立窗口"Desktop"之上运行渲染进程,这样就可以防止被恶意控制的renderer进程打开新窗口或记录键盘输入。

沙盒化渲染进程(Sanboxing the render)

把WebKit放到一个独立进程中运行,我们就有机会严格控制它对系统资源的访问。例如,我们能够保证渲染进程只通过它的父浏览器进程访问网络。这可以防止打开新窗口和捕获击键对渲染进程的干扰。

归还内存(Giving back memory)

鉴于渲染引擎运行在单独的进程中,很直接的,就可以给予隐藏tabs低优先级。通常,最小化窗口时,将使对应的进程把它们的内存放入可用“内存池”。内存不足时,Windows将把会首先把这部分内存交换到磁盘上,之后才会交换高优先级内存,这帮助用户可见的程序变得更流畅。我们也可以对隐藏tabs应用这一原则。当一个渲染进程没有顶层tabs时,我们可以释放该进程的“working set"
size,以提示系统在需要的时候可以首先把它的内存交换出去。

在内存不足时,这帮助我们更好的使用内存。很少使用的后台tabs的内存可能被完全换出内存,同时前台页面内存可以全部加载到内存。与此相反,在单进程的浏览器中,所有的tabs页面的数据随机分布在它的内存中,不可能清晰的区分在使用和未在使用数据,这对性能和内存都是一种浪费。

原文:http://www.chromium.org/developers/design-documents/multi-process-architecture
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: