Google Native Client:是Web的前进还是倒退?
就像是坚定的Web信徒一样,资深开发者Chad Austin也非常认同Google Native Client技术。
他认为web就是一个编程平台——它不仅可以跨越不同的设备,还能能引发世界范围内的技术企业的竞争——Native Client能够将其他需要在硬件环境中执行的语言引进这个平台,这其中包括C、C++和其他高效的“native”语言。
Native Client——一个Google花费了三年多时间开发的开源项目——专门用来支持在web浏览器中安全运行本地代码,它使得web apps能够与本地apps同场竞技,web apps也能与完成传统软件的功能,如3D游戏、视频编辑等等。
这位开发者在他的博客中表达了对Native Client的看法:“Native Client推动了web技术,web将成为像Windows和iOS一样的一流开发平台”。
有人支持Chad Austin的看法,但也有人认为他的话自相矛盾。反对者认为使用Native Client开发的Apps根本就不能被称为web apps。如果将本地代码加入到浏览器中,这将破坏web原本的样子:即应用应该与机器无关。
反对者声称:“web平台与native平台不同,也不应该把它弄得跟native平台一样,正是这种不同,给开发带来了好处。”
Firefox浏览器的开发商Mozilla也不看好Native Client。今年一月份,Austin在推出这个开源项目时,还附加了一个标题“Mozilla对Native Client的排斥妨碍了开放的Web的发展”,而这一观点引起了大家激烈的争论。
在 Hacker News的开发者讨论区,两种声音展开了激烈的讨论,双方都出现了一些没有意义的争吵,一个编程人员表示“Native Client就是一堆马粪”,甚至还有一些更加刻薄的攻击。
当然。也有一些是关于技术层面的讨论,比如对于Native Client能否持续下去的探讨。另一些是有关web应该做什么以及不应该做什么的讨论。在很多时候,这两个方面其实很难分开。
今年秋天Google已经计划将Native Client加入Chrome浏览器中了,但是它最终的命运将交给开发者决定,不论这些人是否支持Chad Austin的观点。
Native Client想要运行下去,Google除了要很好地解决技术问题外,还得处理开发人员对web的信仰问题。开发人员对自己的信仰表现得相当敏感,尤其是涉及web时。
寻找支持多种语言的web
Brad Chen表示:“在浏览器上,你可以使用任何语言,就像使用JavaScript一样。”Chen在Google负载监管Native Client项目,他认为Native Client将使得浏览器摆脱JavaScript的制约(JavaScript是90年代中期由Netscape开发的web脚本语言)。
Chen承认,“JavaScript确实是一个很棒的语言,并且它还在不断发展”,但他表示“很多很好的软件并不是用JavaScript写的,而且有很多优秀的软件开发人员他们更习惯用自己熟悉的语言编写应用,而不是Javascript。”(Chen在Harvard大学有着四年的教学经验,在加入Google以前,他曾在Intel担任了许多年的软件工程师。)
如果Native Client项目能够取得成功,那么web环境中将有更多的语言可供选择。它为C和C++以及许多其他的语言提供了能够在web平台上发挥的机会,就像JavaScript一样,能够有更好的移植性和安全性。
这个目标相当远大,Google认为他已经完成了一半的工作:安全部分。而移植性的工作将在后面继续跟进。
Native Client就像是一个“sandbox”,让native代码安全地在浏览器中运行。JavaScript是一个解释型的动态语言,可以隔离恶意或是有漏洞的代码,但是像C和C++这样的native语言可以访问底层硬件设备,但是却无法提供代码安全保障。Native Client试图为native语言加上这种保护机制。
Google的工程副总裁Linus Upson表示:“web的重要功能之一就是必须保证所有的连接都是安全的。用户可以通过internet访问某个未知服务器上的代码。以往,用户要使用一个native app,必须先下载它,然后还得安装。而Native Client可以让用户像下载JavaScript一样下载任何native代码并运行这些代码,它可以保证所有的代码都是安全的。”
这个sandbox酝酿了20年
Native Client的灵感来源于90年代初期California Berkeley大学的一个学术团队发表的一篇论文。这篇论文介绍了一种过滤native代码的方法,类似于“基于软件的错误隔离”的概念。事实上,该系统使用了一种特殊的指令序列保证机器上的代码程序满足一定的安全性要求,它能够分析生成的代码并判断代码是否是安全的。
但这里的问题是:x86上的指令集与现代的Intel以及兼容Intel的处理器上的指令集有所不同。Google通过使用嫌少使用的“段寄存器”解决了这一问题。受到MIT和Harvard的Stephen McCamant与Greg Morrisett的论文的启发,Google开发了一个能在x86甚至更低版本的机器上运行的系统,使得native代码能够以最高的效率执行。Harvard的Morrisett教师告诉Register“他们真的将这个想法实现了,现在他们已经有了一个非常棒的工具来实现他们想要做的东西了。”
使用x86的32bit指令集,Native Client使用段寄存器限制程序读写的内存范围,确保一个程序不会溢出。但它还有一个改进的编译器,可以将代码限制在一个范围以内。
通常程序将从内存中的数据读取到寄存器中,然后根据地址信息跳转到相应的位置。但Native Client中,编译器会预先计算出地址的值,并判断目标地址的指令不是恶意或是错误的指令,然后代码才会跳转到相应的位置执行。
此外,校验器需要确保程序不会跳过编译器加入的额外指令。Morrisett 指出:“你必须添加一些检验跳跃是否溢出的算法。但关键的问题是,一个程序可能被设计成故意绕过这些检验算法,你可以保护一个指令的跳跃,但是你无法保护下一个。”
为x86编写一个校验器是非常困难的,因为x86的指令长度不是固定的。如果指令长度不一,就需要花费很多时间查找不安全的指令。你必须按照原始字节顺序查找错误的代码,并且需要假设错误的字节可以在任意一个位置发生。
但是,MIT的一个校友McCamant发现可以使用填充伪字节解决简化这一问题。Morrisett 说“在RISC机器上(指令长度是一致的),只需要解析一次。但是在x86上,则需要多次解析,要检查所有的可能性几乎是一件不可能的事。解决这个问题的关键就是必须按照规定的方式排列指令。”Google吸收了之一想法。还通过使用段寄存器替身了系统的性能。Google优化了McCamant的方法。
Google的目标
和其他的软件一样,Native Client也有自己的安全漏洞,据Morrisett所说,这的确为代码校验器带来了困扰。在2009年,Google举办了一个测试Native Client bug的比赛,期间的确发现了一些问题。但是Morrisett认为现在的Native Client已经相当健壮了。
值得一提的是,Native Client不仅在x86上实现了软件级的错误隔离,它的速度基本与native代码相当。据Morrisett所说,沙箱功能只带来了5%的时间开销,这使得Native Client性能远远优于JavaScript。
他表示:“与浏览器上运行的其他代码相比,Native Client具有很大的性能优势。这使得在浏览器中做大的图像渲染和大规模数据处理成为可能。”
还有一点,就是Native Client能够提供多种并发执行的方法,而这是JavaScript无法做到的,在做向量运算上它也更具优势。对Google而言,这意味着浏览器将可以开发3D游戏、视频编辑以及其他性能要求很高的应用了,这些应用能够更容易移植到web平台上了。已经存在的native app必须使用Native Client来移植,但是起码开发者不用重头来过了。他们可以直接使用已经编写好的代码。
这非常吻合ChromeOS的概念,ChromeOS是Google的操作系统,试图将所有的应用程序都放入浏览器中。将已有的3D游戏和其他桌面应用程序放入浏览器并不是ChromeOS的目标。但是,Native Client为Google的操作系统打下了很好的基础,它最终的目标其实是整个web上的所有新应用。
Google的Linus Upson表示,JavaScript在处理整数方面做得不错,但是它还不能很好地处理向量运算,这方面native代码具有明显的优势…虽然并不是所有的软件都有这些需求,但是如果他们需要,这意味着使用JavaScript的性能将会相当糟糕。
最直接的一个例子就是3D游戏。它需要处理很多的运算,现在基本都是用C++开发的,如果使用Native Client,开发者就可以直接使用已有的代码库。这也会给web代来更多更加有趣的游戏。
现在的问题是Native Client并不是是web——至少目前还不是。虽然Google即将把它整合到Google浏览器和Google浏览器操作系统中,但它还不是完全意义上的web。
Opera可能也会拒绝Salt和Pepper
Native Client 通过一个称为Pepper的API被加入到Google的Chrome浏览器中。Google通常将Native Client简称为“NaCl”,正好可以被成为“Salt”(盐)。Pepper将取代长久统治浏览器插件接口的NPAPI(Netscape开发的),这样Native Client就能在所有支持JavaScript开发的浏览器上安全运行了。
Brad Chen表示“我们的目标是开发一个没有边缘效应的执行插件——完全无需与外界交互——我们认为sandbox已经达到了我们的要求。但问题是,如果你不与外界交互,甚至是不与浏览器交互,那你其实什么也做不了。这就是为什么我们还要开发Pepper的原因。Pepper允许Native Client访问所有JavaScript可以访问的资源”。
Greg Morrisett认为Pepper的加入给技术安全带来了些问题,但是Google认为Pepper远比NPAPI安全得多。Pepper最初是参考旧的Netscape的API插件开发的,不过后来又重新对他进行了设计。
Google已经使用Pepper API将Adobe的Flash Player整合到了Chrome中,而且在九月末推出了Native Client在浏览器上的稳定版本,并对第三方native apps开放。
这并不会使得Flash成为web的一部分,也不会使得Native Client成为web的一部分。Native Client还没有整合到其他的浏览器上。它也并不是一个标准。它需要使用一些特定的指令集。除了x86版本外,Google还开发了64位x86和ARM版本,但这还远远不能满足所有web设备的需求。
Google也意识到了这个问题,并且正在积极想办法解决这个问题,Linus Upson表示Native Client刚刚推出的版本要求所有的Native Client apps必须经过处理平台的特殊编译。Chrome只接受通过Chrome Web Store发布的Native Client apps,并且也只会通过Chrome Web Store发布那些支持32位和64位x86的应用(Native Client的ARM版本尚未准备好)。
Chen表示“我们并不想为web指定一个指令集。如果我们发布一个应用,我们会保证它适合将来所有的架构。”
但最终的目标还是开发一个能够支持所有处理器的Native Client。这种可移植Native Client(Portable Native Client)——PNaCl已经被提上了开发日程。简单说来,这个版本的Native Client不再产生x86或ARM指令,而是将native代码使用一个编译器翻译成二进制代码,这个编译器来自LLVM(low-level virtual machine)的开源项目。浏览器下载二进制代码后,PNaCl将它转换为机器语言并可以像Native Client运行机器代码一样运行这些代码。
这使得Native Client就像JavaScript一样。但还存在一些问题。Portable Native Client 可能需要一些额外的开销。Upson表示现在PNaCl通常执行速度要优于JavaScript,但是它的启动速度还不够理想。在正式推出PNaCl以前,Google希望能够解决这些问题。但即使它真的能够战胜JavaScript,其他的浏览器也不一定会接收它。虽然Apple和Microsoft尚未对Native Client表态,但Mozilla和Opera已经明确表达了自己的反对立场。
Berners-Lee的旧同事,现担任Opera的首席技术官的Håkon Wium Lie(音译)说到:“Tim Berners-Lee的意思听起来似乎NaCl希望web回到过去那个糟糕的时代”。
Mozilla指出DLL的问题
Wium Lie认为虽然Native Client能够提升web的性能,但是浏览器开发者应该使用标准的web工具,包括HTML、CSS和JavaScript。他告诉The Register:“web平台具有开发者需要的所有工具,如果真的缺少什么,那也应该是去修正web平台,而不是到别的平台上寻求解决甚至是创建一个新的平台。而Native Client正好违背了这样的思想:他们正在开发一个新的平台——或是将旧的平台引入到web中。我认为这完全没有必要。这只会给web带来复杂性和安全性问题,并且将混淆web平台的重点”。
他认为越简单的东西越好。“HTML的成功正是因为它的简单。只有简单的东西才容易被人学习,简单的东西安全性问题也容易解决。如果在web中加入一个平台,那么需要处理相当多的安全问题。”
他表示,Web的标准需要扩充,并以新的WebGL标准为例。但这并不意味着运行在浏览器中加入native代码。“WebGL提供了硬件和图形处理器的访问接口。但我们并不需要二进制代码。Native Client可以开发出web游戏,但这个意义不大。”
他不仅否定了Google的想法,甚至否定了Google的措辞。Wium Lie认为Native Client并不属于web。对Google而言,Native Client基本上是web的。而Opera认为Native Client是一个浏览器插件。Google则认为它是浏览器的一部分,这一点不同于Java和Silverlight。
Mozilla的想法与Opera基本相同,但他看得更远一点。Mozilla的开源宣传人员Chris Blizzard表示,使用JavaScript,你可以通过改进浏览器来提升程序的性能,而Native Client则做不到。web最大的优势就是它是跨平台的,这是它被推广的最重要的原因。Native Client实际上并未解决web能解决的任何问题。
一旦你下载了native代码,那你将无法优化你的浏览器了。一切都已经设定好了。要知道浏览器在过去几年的发展中已经得到了非常大的改进。这些改进使得应用程序的速度得到了明显的提升。”
“如果选择Native Client,以前所以的改进都将失去意义。web上的创新性将消失不见。基于源码的开发意味着我们能够优化连用户都没有想到的事情,并且可以直接交付给用户,开发者能够做任何事情。”
但Blizzard也指出,native代码毕竟是native代码。“你该如何处理版本兼容性的问题?你如何解决DLL的问题?又该如何解决Lib C的问题?这也是Microsoft操作系统不断膨胀的原因,出于向后兼容性的考虑,他们推出了多个版本的内容。我们在浏览器上也面临的了同样的问题。附加的二进制代码使得开发者更难更新了。”
“我认为native代码的世界并不是我们想要的。我认为web是一种进步。我们都不想让它退回到二进制代码的时代。以前也有过类似的工具,比如Microsoft的ActiveX就是一个例子。Native Client可能安全性做得更好,但是本质上他们并没有什么太大的区别。”
Native Client常被拿来与ActiveX作比较,Microsoft想通过ActiveX在浏览器中加入C++、.NET开发的控制软件,但却遭遇了滑铁卢。ActiveX有严重的安全隐患,可能导致IE下载带有病毒的代码。但是Blizzard并没有拿安全性与Native Client做比较。他表示,即使Native Client真的是安全的,它也不是什么好东西。
和Hacker News上的开发者一样,Opera和Mozilla的态度也夹杂了他们的信仰问题。毕竟,是开发者和浏览器提供商推动web的方向。Mozilla占有25%的浏览器市场,所以即使你不同意他们的立场,他们的立场也会有很大的影响力。如果你真的要用Native Client开发应用,那么你的应用只能在一部分主流的浏览器上运行——这最终将会导致在线apps被分割为多个部分。
Google为自己的项目辩护
Google理解大家的抱怨,但他认为他们最终能够获得认同。Brad Chen 指出“我们将Native Client的源码公开,并尽量保持与web标准的一致性,因为我们确实希望能够为web发展做出贡献。但这个技术确实是相当复杂的。我们并没有期望其他的浏览器能够立刻接受它。我们的工作就是去证明它不仅是安全的,而且是非常实用的。”
Chen和Upson认为ActiveX的类比其实没有太大的相关性。Upson 指出“Native Client并没有加入什么新的功能,都是原来HTML5和JavaScript支持的功能。它只不过是允许C和C++程序访问而已。它完全符合web的安全模型,这一点与ActiveX完全不同。”
当被问及Native Client与ActiveX的区别时,Chen换了一种表达方法“你可以先问问JavaScript和ActiveX的区别。它是安全的并且是可移植的。而Native Client将安全性和可移植性放在了首位,我不认为ActiveX也一样。”
还是那个话题,可移植性目前还没有做得很好。但是显然,Google认为他们最终可以使用PNaCl解决这个问题,并且在启动和执行性能方面都优与JavaScript。
Chen和Upson还提到了Emscripten项目,这个项目诣在将LLVM的二进制代码迁移到JavaScript中。Upson表示,即使其他的浏览器不支持Native Client,也可以使用它将Native Client apps推广到整个web上。
被问及Bizzard提出的“提升浏览器就能提升apps”的看法,Upson指出Emscripten可以很好的解决这个问题。“你可以使用C编写app,然后在Native Client中运行,或是使用Emscripten将它转化为JavaScript然后再运行。这样就与原来的模型一致了。当然Native Client提供了一些Emscripten不具备的功能,但我们可以继续提升Native Client的运行环境”。
问题是添加的功能仍然会导致额外的开销,使它的性能很难与JavaScript相提并论。
最后,双发都提出了一些有意义的论点。但是不论Mozilla和Opera开发者社区的立场如何强大,Google都将坚定地推动Native Client——并准备将它推得更远些。
编程人员眼中的理想web
在将Native Client加入Chrome后,用户可以在浏览器中下载并运行native apps,Google还计划在Native Client sandbox中运行Chrome——只是部分Chrome功能。Upson表示:“我们也是常人,我们当然也会犯错,我们有可能会留下一些错误,有些错误可能就变成了安全漏洞。”
“Native Client的设计可以保证即使是恶意的代码也无法影响你的电脑。如果能在我们的Chrome代码中加入这样的sandboxing技术不是一件很棒的事情吗?如果我们在Native Client中运行我们自己的代码,即使我们自己的写下的错误也不会变成安全隐患了。”
比如,Google可以在Native Client中运行Chrome的PDF查看器,浏览器部分组件需要访问本地文件系统,而这可能会被sandbox阻止,但是Google保证其他的部分可以访问。
Google还考虑是否能够在服务器端加入Native Client。Google新推出的一个访问学者计划正在探讨如何在NaCl sandbox中运行高性能的服务器端apps。看起来Google已经瞄准了sandbox native代码。这有什么问题吗?据Upson所说,Native Client可隔离代码的错误以及恶意访问。
其实web apps上还存在各种可能性。使用Native Client,你能将各种代码放到浏览器上运行,包括浏览器提供商的代码甚至是第三方插件的代码都可以。这样,开发者就不用再等到浏览器支持音频解码器后才能编写音频web应用了。他们可以直接使用Native Client发布自己的解码器。
Unity技术一直被用来为Unity平台上的浏览器3D游戏提供插件,但现在这个来自San Francisco的工具能够将这个游戏平台移植成一个Native Client app。这意味着,开发者可以直接在Chrome上发布基于Unity的游戏,而不用再要求用户安装任何插件了,同时,他们还可以使用Native Client sandbox。
Unity的战略副总裁、引导了公司与Google Native Client合作的Brett Seyler表示:“对我们来说,最重要的是尽可能让用户通过最简单的方式在web上访问Unity。随着Chrome引入Native Client,Unity的开发者将能够使20%的浏览器用户可以不用安装任何插件就能直接使用Unity了。减轻用户操作的web应用都能为我们带来好处”。
同样的,Microsoft的.NET平台开源典型Mono的开发者也在做Native Client的相关工作。他们希望能够使得最新的Mono版本能够在浏览器中访问。
Robert Isaacs是一个独立的程序员,他开发了一个支持经典DOS游戏的Native Client平台,Native Client在这个项目作为插件安装后,你将不用再安装任何其他的插件了。他说到:“我认为Native Client是一个集成了所有插件的插件。如果你想在浏览器中运行.NET程序,只有Native Client能够帮你做到。这样你就不用等到Microsoft推出一个新的Silverlight版本,并且还得让所有用户都安装这个版本了。你可以直接在Native Client上部署你的最新Mono版本了。”
“Native Client介乎native apps和web apps之间。”
确实是这样。但是Isaacs对Native Client满是溢美之词——而Mozilla、Opera和一些人则对Native Client的模棱两可相当介意。每个人对web的理解都有所不同。
时间会检验一切,只要是好的东西最终会克服那些反对的声音。由于Chrome控制了20%的浏览器市场——Google很容易在web上发挥自己的影响力——Native Client已经有了最有力的支持者。Chad Austin 指出:“Chrome有这个实力,它是目前发展最快的浏览器,而且Native Client现在已经受到了相当多的关注,我认为它很容易吸引到开发者。如果它能发展下去,我觉得Google将在未来的web中占据非常有利的地位。”
但并非所有人都认同Chad Austin的观点。
英文链接:Google Native Client: The web of the future – or the past?