12月21, 2016

【译】多进程架构

题目:多进程架构

原文链接:Multi-process Architecture

不像大多数web浏览器,谷歌浏览器使用了许多操作系统进程来保持各个网站相互分离和计算机的其余部分的分离。通过这篇博客,我将告诉你,在当今的网站,为什么使用混合架构体统会是一个巨大的成功。同时,我也会谈到,浏览器的哪一部分数据哪个进程,在什么情况下浏览器会创建新的进程。

1.为什么在浏览器中使用多进程

当大多数现在的浏览器被设计出来的时候,有那么一段时间,网页是很简单的,有极少的代码或者说干脆就没有代码。那么浏览器渲染在同一个进程中去渲染你所有浏览网页,以保持资源的低利用率就很合理了。

但是,现如今,我们可以看到主要转向活跃的网页内容,从拥有大量JS和Flash的网页到完整的“网络应用app”,比如:Gmail。大量的app都是内嵌浏览器,就像普通的应用跑在一个操作系统上。正如一个操作系统,浏览器必须保证这些应用程序是彼此分离的。

基于这个现象,随着时间的推移,浏览器中渲染HTML,JS,CSS的那部分变得越来越复杂。渲染引擎在发展的过程中,频繁出错,这些bug甚至可能会导致引擎崩溃。同样,渲染引擎面对的是不可信的,甚至是网络恶意代码,这些代码可能会利用bug在你的计算机上安装恶意软件。

全世界,这种把所有事物都放在一个进程中处理的浏览器 面临着健壮性,响应能力以及安全问题的挑战。如果一个Web应用程序在渲染引擎中导致崩溃,它将占用浏览器的剩余的部分,包含任何其他打开的Web应用程序。Web应用程序通常要在一个单线程上相互竞争CPU的时间,有时导致整个浏览器没有响应。安全也是一个值得思考的问题,因为渲染引擎中利用漏洞的网页可能会占用整个计算机。

当然,不一定就这一种方式。Web应用程序通常在你的浏览器中是被设计为彼此相互独立的运行,它们甚至可以平行的运行。同样,它们也不用使用你的磁盘或设备。安全策略是在网站确认后才会使用,目的就是为了让你在浏览大多数网页时不必担心你的数据和计算机的安全。也就是说,在不阻塞各个Web应用程序的情况下,使它们相互分离是可以实现的。同样,对于像Flash这样的浏览器插件也是如此,它们与浏览器松散耦合,并且可以毫不费力地与浏览器分离。

谷歌浏览器利用这些属性从浏览器自身把Web 应用程序和浏览器插件分到不同的进程中去。这意味着,渲染引擎在一个Web应用中崩溃就不会影响到浏览器本身或是其他的应用程序。这也意味着,操作系统可以平行的运行Web应用来提高它们的相应能力,同时,当一个特殊的Web应用或插件停止响应时,浏览器不会锁住。这也意味着我们可以在限制性沙箱中运行渲染引擎进程,如果漏洞发生有助于限制破坏。

有趣的是,使用多进程意味着谷歌浏览器可以有它自己的任务管理器(如下图),你可以在浏览器的名称栏右击鼠标来唤起。这个任务管理器可以帮你追踪每一个Web应用和插件的资源使用情况。同时,你可以在不重启整个浏览器的情况下,杀死没有响应的Web应用或是插件。

alt

基于以上所有的原因,谷歌浏览器多进程架构可以比单线程的浏览器更加健壮,高响应,安全。

2.每个进程是如何运行的

谷歌浏览器创建了三个不同的进程:浏览器进程,渲染器进程和插件进程。

浏览器进程。在管理tab,窗口,和“谷歌”的浏览器方面只有一个浏览器进程。这个进程同时处理所有的磁盘通信,网络通信,用户输入以及显示器,但是它并不解析或渲染网站内容。

渲染器进程。浏览器会创建很多渲染进程,每一个都负责渲染网页。这些渲染进程包含所有的处理HTML,JavaScript,Css,图片等资源的复杂逻辑。我们使用开源WebKit渲染引擎来实现这一点,这也被苹果的Safari浏览器使用。每一个渲染引擎都运行在一个沙箱中,这意味着它几乎没有直接访问您的磁盘,网络或显示器。所有web应用的交互,包括用户输入事件和屏幕绘制,必须通过浏览器进程。这允许浏览器进程监视浏览器的可疑活动,如果它怀疑发生了漏洞,则杀死它们。

组件进程。组件进程也为每种正在使用中的组件创建了一个进程,比如:Flash,Quicktime,或Adobe Reader。这些进程只包含插件本身,通过使用一些粘附代码来与浏览器和渲染器进行交互。

3.什么时候浏览器应该创建进程

一旦谷歌浏览器创建了它的浏览器进程,它通常会为您访问的网站的每个实例创建一个渲染器进程。这个方法主要的目的就是保持不同的网站相互独立。

你可以把这个想成为浏览器不同的tab使用不同的进程,但如果两个tab相互关联并且展示相同的网站则允许它们共享同一个进程。举个例子,如果一个tab使用js打开另一个tab,或者如果你在一个新的tab中打开一个相同的链接,这些tab就会共享渲染进程。这些tab中的页面通过js进行通信,并共享缓存的对象。相反,如果您在标签页的位置栏中输入不同网站的网址,我们将为该标签交换新的渲染器进程。

对我们来讲兼容已经存在的网页是很重要的。因为某些原因,我们用一个网站的注册域名来定义一个网站,比如:google.com 或者bbc.co.uk。这意味着我们会考虑像mail.google.com和maps.google.com这样的子域名视为同一网站的一部分。这是很有必要的,因为有一些情况,来自不同的子域名的tab也许会尝试进行相互沟通,所以我们要尝试保持他们在相同的渲染进程中。

然而,还是有一些针对基础方法的注意事项。如果你创建太多的tab,你的电脑就会打开的很慢,所以我们对我们创建的渲染进程设置一个上限(大多数情况是20)。一旦我们达到了这个上限,我们将开始在新的tab上复用已经存在的渲染进程。因此,相同的渲染进程就有可能被不只一个网站使用。我们还没有在他们自己的进程中放置跨站点框架,我们还没有为所有类型的跨站点导航切换tab的渲染器进程。到目前为止,我们只通过浏览器的“chrome”(如位置栏或书签)交换标签页导航进程。除了这些注意事项,谷歌Chrome通常在通用方法中将不同网站的实例彼此分开。

对于每一种类型的组件,当你第一次在网页中使用它时,谷歌Chrome将创建一个组件进程。在你使用特殊组件关闭所有的页面后的一小段时间后,我们将销毁这个进程。

随着我们改进我们在渲染器进程之间创建和交换的策略,我们将发布未来的博客条目,同时,我们希望您在使用Google Chrome时了解多进程架构的一些优势。

本文链接:https://www.imwineki.cn/post/Multi-process Architecture.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。