导读:在开发人员编写代码而无需额外配置 Wasm 模块,用以在不同环境中同时部署应用程序之前,还有一段距离。
在我们介绍 WebAssembly 无缝支持当今使用的大多数(如果不是全部)主要语言之前会发生什么之前,我们先说明一下现状:在开发人员以零配置编写代码之前,我们还有一段距离要走。 Wasm 模块用于在多个不同环境中同时部署应用程序,从云部署到物联网设备再到本地服务器。
使用不同编程语言编写的不同应用程序应该能够在单个模块中运行。
从本质上讲,微服务封装的模块应该能够用于跨多个不同的环境部署服务,并提供应用程序更新,而无需重新配置端点。理论上,只需在模块中配置应用程序即可,一旦模块内部的工作完成,就不用单独重新配置部署该模块的单个环境。
对于在浏览器、CPU 核心和Fermyon Spin SDK上运行的 WebAssembly 应用程序,WebAssembly 仅支持 Rust 和 Go语言 。一个甚至可以容纳 Rust 和 Go 的组件模型尚未最终确定,更不用说单个 Wasi 目标上的所有语言了。
是什么引起的滞后?
它很大程度上取决于最后一个 WebAssembly 系统接口 (WASI) 层以及每种编程语言与它的交互。
目前,Fermyon Spin框架可以运行任何语言的应用程序,这些语言可以编译为具有 WASI 支持的 WebAssembly。
然而,带有 Spin SDK 的语言支持高级功能,如完全集成的key/value存储、NoOps SQL 数据库和内置 HTTP 客户端,Fermyon Technologies联合创始人兼首席执行官Matt Butcher表示, “现在,Rust、Go、JavaScript /Typescript 和 Python 均有 Spin SDK,”Butcher 说。“当今年晚些时候发布组件模型时,支持组件模型的每种语言都将获得 Spin SDK 的访问权限。”
为了确保不同的编程语言可以在 WebAssembly 模块中协同工作,它们都需要创建一个转译层。Enterprise Management Associates (EMA)分析师Torsten Volk表示,这一层有助于将其独特的系统调用转换为 WASI 可以理解的格式。
“系统调用是程序对存储网络或计算能力等资源发出的请求。虽然这听起来都很简单,但实际上实现将相当复杂,”沃尔克说。每种编程语言都有自己的一组系统调用,并且它们之间可能存在本质的不同。沃尔克说,它们需要仔细调整,以便 WASI 能够理解它们。
正如 Volk 所说明的,当编程语言具有旨在访问文件系统的系统调用时,可能会出现一些问题:
如果WASI不直接支持此系统调用,则转换层必须弄清楚如何将其映射到 WASI 兼容的调用。这需要对编程语言的系统调用和 WASI API 都有深入的了解,这让它成为一项非常复杂的任务。
有的系统调用可能要求比 WASI 所能提供的更多的系统访问权限。这些调用可能无法直接转换,并且可能需要更复杂的解决方法。
转换系统调用的过程需要时间,并使用基础设施资源。这可能会使保持一致的性能变得具有挑战。Volk 说,本质上,虽然 WASI 为不同语言在 WebAssembly 中互操作提供了一种方法,但使每种语言的系统调用与 WASI 兼容的过程可能相当复杂并且占用资源。
WebAssembly 社区组 (CG) 和 W3C 内的 WASI 子组织最近针对 WebAssembly 核心、WebAssembly 组件模型、WASI 和其他基于 WASI 的接口发布的 WebAssembly 路线图已经涵盖了编程语言支持。
组件模型提案是在核心规范之上开发的,包括 WebAssembly 接口类型 (WIT) IDL,而 WIT 是用于描述组件接口的高级类型语言(组件模型添加了高级类型)。
字节码联盟技术标准委员会主任兼Cosmonic主任Bailey Hayes在博客中写道,具有导入和导出接口的级别类型,使组件可组合和可虚拟化。Hayes 还提道,这对于允许不同的编程语言在同一模块中运行非常重要,因为它允许创建和组合最初用不同编程语言编写的组件。
Cosmonic首席执行官兼联合创始人Liam Randall说:“这种标准化还促进了从各种语言创建组件的语言工具与 WebAssembly 系统接口 (WASI) 定义的热插拔模块,它们之间能更好的协作。” 这对开发人员来说意味着我们现在可以使用来自不同语言孤岛的代码,为 WebAssembly 生态系统创建一个强大的“更好地在一起”的故事。”
Rust 永不眠
Wasm 最终需要能够为超越浏览器的应用程序,提供更多充分运行流行的语言支持。
目前,Wasm 可以在浏览器中运行的语言包括 JavaScript、Python、Rust、Go、.NET、C++、Java 和 PHP。但如上所述,Wasm 的开发需要走很长的路才能对所有人都可行。
“到目前为止,JavaScript-in-WebAssembly 实现了基于 QuickJS 的引擎,而该引擎并非广泛使用的 JavaScript 运行时。Fermyon 正在转向 SpiderMonkey,这是一款为 Firefox 提供支持的强大且经过实践考验的 JavaScript 引擎。”Butcher 说道。“这一变化将为 WebAssembly 增强 JavaScript 和 TypeScript。我们将看到完整的功能集合、超快的性能以及与许多现有 JavaScript 包的兼容性。”
该报告包含了 RedMonk 排行榜中的前 20 种语言。
WebAssembly 1.0 的实现,表示至少有一个浏览器实现 WASI 接口,该语言至少支持 WASI 提案的预览版,并可以运行在 Fermyon Cloud、Spin 和 Fermyon 等平台上。
生产环境中 WebAssembly 应用程序最兼容的语言是 Rust 和 C++ 或 C。也就是说,在RedMonk 语言排名中的前 20 种语言中,有 16 种至少有基本的浏览器支持。
Hayes 说:“Rust 和 C/C++ 等不需要垃圾收集器的静态类型语言是最早添加 WebAssembly 作为目标的语言之一。使用系统级语言为虚拟堆栈机添加新的字节码目标更加简单,不需要在解释器或垃圾收集器中进行编译。“
但 Rust 与其他软件的不同之处在于它与 WebAssembly 共同进化。Hayes 表示,许多在SpiderMonkey引擎中从事 WebAssembly 工作的 Mozilla 工程师也是 Rust 语言成长和发展的一部分。
Hayes 提到,WebAssembly 的主要目标是生成极其紧凑的字节码,允许生成微小且加载时间高效的二进制文件,同时也是内存和沙箱安全的。Rust 具有零成本抽象,对于投资创建内存安全程序的工程师非常有吸引力。“在很多方面,WebAssembly 和 Rust 都吸引了彼此的目标和关键优势”。
对于许多开发人员或任何只想编程的人来说,Rust 是比较难学习的。但是又有不少排行榜指出 Rust 一直被评为开发者最喜爱的语言。
Hayes 说:“直到 2015 年 ,Rust 发布第一个稳定版本,我才开始关注 Rust。2015 年的有趣之处在于,它也恰好是 WebAssembly 设计工作开始的一年。”
Butcher 指出,C 也是针对 WebAssembly 支持的原始语言,该规范的工作组密切关注 C/C++ 生态系统。“Rust 与 WebAssembly 一样,最初始于 Mozilla,并与 WebAssembly 一同成长,”Butcher 说。“WebAssembly 的一些最活跃的开发人员也致力于 Rust 生态系统的关键部分。所以这些技术是共同进化的。”
Python
一旦 Wasi 后端的组件标准最终确定,Python 支持将特别受欢迎。
这是因为 Python 的巨大吸引力在于大量易于使用的库,这些库通常可以让开发人员无需编写大量代码即可完成 80% 甚至 90% 的工作。
假设我想将这篇文章存储在 NoSQL 数据库中,例如 MongoDB 或 Cassandra。首先,我们可以使用 Selenium 库在 TNS 网站上查找和检索文章,然后我们可以利用 Pandas 来识别文章的各个组成部分并将其存储在方便查找的数据库中,例如标题、图像、文本、链接等框架。最后,我们可以使用 Cassandra 驱动程序库或 PyMongo 来连接、验证文章并将其写入我们选择的 NoSQL 数据库。
Butcher 指出,在 Fermyon框架中,Python 支持“是我们的重点,我们最近发布了更新的 Python Spin SDK,并且已经在努力开发新版本,”Butcher 说。“在我们能够支持现代 Python 人工智能和数据处理中使用的通用库和工作负载之前,并不会放慢势头。”
Volk 表示,现在的情况与 Kubernetes 早期非常相似,当时保存应用程序状态、存储应用程序数据、确保应用程序性能以及与外部系统交互“仍然很棘手”。“
现在我们需要简单的一种方法,找到在现实项目中的当前局限性,并不断突破界限,就像对 Kubernetes 所做的那样,但作为奖励,我们最终可以将整个应用程序(包括其服务器和容器运行时)存储在容器注册表中,以进行统一的包部署。”