WASM:起于前端,不止前端

7,734 阅读9分钟

写在前面

WASM(Web Assembly)作为一项诞生自浏览器的技术,已经被广泛应用到前端开发的许多方面。但经过短短几年的发展,WASM 早已不是印象中那个只用来在浏览器中处理一些计算密集型任务的工具了。如今的 WASM 正带着属于它的完整生态和独特优势入侵多个领域。本文将重点阐述 WASM 在浏览器之外的发展现状、应用场景以及未来的发展趋势。

起源:一种拓展浏览器能力的新技术

WebAssembly 是一种运行在现代网络浏览器中的新型代码(Code)以提供特定功能,特别是在性能方面。它一般不会被直接编写,而是为诸如 C、C++ 和 Rust 等底层语言提供一个高效的编译目标。目前,WebAssembly 已成为与HTML、CSS 以及 JavaScript 并列的web领域第四类编程语言。

image

初始应用场景

WASM 的诞生,就是来源于想在浏览器原生支持非 JS 语言编写的一些工具,特别是视觉、格式转换、编解码算法等一些工具库。因此最初大家并没有跳出这个范畴,WASM 更多被运用在以下两个方面:

  1. 在浏览器中原生运行已有的工具库:视觉领域的 OpenCV,视频编解码领域的 FFmpeg,都是十分成熟的领域解决方案。WASM 之前更多依赖引入服务端或 JS 版的实现,现在可以原生支持;

  2. 替换浏览器应用中计算密集型的模块:如 Web 3D 中复杂的数学运算、可视化中的布局算法执行、文件对比、加密解密等。

整体来看,WASM 的诞生拓展了浏览器本身的能力,特别是一定程度上补足了浏览器端 JS 执行效率的短板。不过最初的应用场景也仅围绕浏览器提升运行速度展开,开发者仍有替代的解决方案,同时还要考虑引入 WASM 之后带来的 JS 与 WASM 的交互开销。

突破:一套完整的应用运行的生态体系

原先的 WASM 更多的是作为一个 Worker 的角色,通过 JS 胶水代码将 WASM 与浏览器 API 等连接起来,共同实现 Web 应用功能。如下图所示:

image

但是,WASM 的机制本质上是将其它语言编译为统一的.wasm中间语言,并通过 WASM 对应的 VM 执行。

image

如果有一套机制可以支持多语言编写,还能够通过 VM 的机制脱离操作系统的依赖,可以跨平台地运行在各种各样的浏览器中,那么为什么只让它和浏览器进行交互呢?让我们来看 WASM 如何一步步逐渐发展起来。

WASM Runtime & WASI

既然 WASM 并不限于浏览器中执行,自然也不需要依赖浏览器的 Runtime,为 WASM 提供独立且轻量的运行时成为 WASM 跳出浏览器之外的第一步。毕竟,WASM 虽然叫 Assembly,但并不是真正意义上的汇编语言,不能直接在操作系统上原生运行。

独立 WASM Runtime 出现之于 WASM 的意义,可以类比 NodeJS 之于 JavaScript 的意义,为 WASM 带来了更多的可能性。我们以最流行的 WASM runtime 之一 -- wasmtime 为例:

image

一个完整的 Runtime,处理包含实际的运行 WASM 程序的 VM,还包括针对 .wasm的编译优化模块和辅助开发与调试工具等。

独立的运行 VM 解决了 WASM 代码跑在浏览器之外的问题,但跑在浏览器之外意味着 WASM 需要直接与操作系统进行交互,而不能完全依赖 JS 这样的胶水语言。类似 NodeJS 中的 libuv,WASM 的 Runtime 同样需要实现特定的 adapter,而如何保证每个 Runtime 的 adapter 实现相同,让 WASM 不用考虑不同 Runtim的兼容性?WASI 给出了答案。

WASI(WebAssembly System Interface),是为 WASM 设计的一套 API,用来约定 WASM 应用与系统的交互方式。其中包括:文件系统、网络(socket)、时钟、随机数等。

image

WASM Runtime 需要包含对 WASI 的实现,同时,WASM 程序对应的源语言也要支持原生库中的系统函数调用编译为 WASI 的函数调用。

拥有 Runtime 和 WASI 之后,WASM 彻底脱离了浏览器,作为一个轻量化、可移植的应用解决方案,带给开发者极大的吸引力。

image

WASM 生态

WASM 发展至今,自身能力已初步成型,随之而来的各种生态也逐渐发展起来,从底层越来越多的语言支持,到上层的应用开发脚手架,甚至 WASM 包管理器和调试工具。WASM 正逐渐丰富自身体系并被被应用在越来越多的领域。

image

应用:一项具有特定领域优势的新方案

突破浏览器限制的 WASM,由于其独特的轻量化和可移植等特性,逐渐被应用在云原生、Serveless、边缘计算等领域。

据统计,2022年 WASM 的应用领域除了占比最大的 Web 开发之外,在 Serveless、容器化、作为插件环境等方面均有大幅的提升。

image

image

WASM 的优势

可移植性

WASM 的可移植性体现在其本身是二进制级别的产物,即一次编译,到处运行。作为对比,一些编译型语言(如 C)需要通过指定不同的 target 多次编译以实现跨平台,而 WASM 由于引入 Runtime 这样的 VM 机制,源语言可以先编译为.wasm,再由 WASM Runtime 在不同平台上运行。

这一机制并非首创,在 Java、C# 等其它编译型语言中已经得到了广泛使用。不过 WASM 具备的其它优势使得它成为独特的存在。

image

image

统一化

越来越多的语言支持编译到.wasm,通过 WASM 这一统一的二进制格式,不同语言编写的程序可以运行在Windows、MacOS、Linux 以及浏览器等平台。对于需要支持多语言的应用,仅需提供 WASM 运行时而不需要关心执行所有不同语言的环境配置。

image

安全性

WASM 天然是沙箱化运行的,WASI 提供与操作系统中资源交互的入口,因此可以严格控制用户提供的 WASM 程序的预期外行为。

轻量化

我们以同样可以做应用隔离并支持多语言应用运行的容器化技术作为对比。

  • 容器技术:将程序运行所需的操作系统库和依赖项打包提供,相当于提供一个轻量的操作系统。

  • WASM:不提供完整的操作系统能力,只提供运行程序的 VM,并提供与系统交互的接口(WASI)。

由此可见,WASM 相比容器更轻量,更适合更上层的应用(应用功能更多地在应用内闭环,与操作系统交互较少)。

image

image

WASM 应用场景

虚拟化技术

用于应用快速构建并便捷分发与运行的虚拟化技术已经是现代应用的基础,虚拟化技术当前以容器技术最为流行,容器与容器编排已成为当今云原生时代的应用基石。而 WASM 有望在虚拟化技术上更进一步,做到更加轻量化。

目前,Docker已宣布支持 WASM,官方称其为 Linux/Windows 容器之外的另一个选择。以构建一个 php 镜像为例,常规的 Linux 镜像、alphine 版镜像和 WASM 镜像的大小对比如下,可以看出 WASM 镜像在体积上有极大优势。

$ docker images

REPOSITORY                     TAG                 IMAGE ID       CREATED          SIZE
php                            7.4.32-cli          680c4ba36f1b   2 hours ago      166MB
php                            7.4.32-cli-alpine   a785f7973660   2 minutes ago    30.1MB
ghcr.io/vmware-labs/php-wasm   7.4.32-cli-aot      63460740f6d5   44 minutes ago   5.35MB

具体如何使用 WASM 镜像可以参考:WebAssembly: Docker without containers!

Serveless

由于 WASM 的轻量化特性,在 FaaS 领域可以实现更快速的启动时间和更小的资源开销。我们熟悉的 ByteFaaS 中的 FaaS Worker, 采用 WebAssembly 技术打造了轻量级函数运行时,实现了极致短的冷启动时间,函数高密部署,极致成本优化,并能有效应对流量突增陡降。

具体可以参考:第十二章 WebAssembly 在 ByteFaaS 中的应用 - 掘金

插件体系

WASM 支持编译自多种源语言的同时,有统一的运行时,很契合使用插件的拓展场景。如在 Envoy 中,处理流量请求的 filter 部分,便可以通过使用 WASM 模块支持开发者使用 Golang 等语言进行进行拓展。目前 API 网关中的部分流量插件,如限流,即采用了这种拓展机制。

image

下文展示了如何使用 WASM 实现一个添加请求 Header 的 WASM 插件,其中涉及到从 WASM Hub 拉取插件并使用 wasme operator 自动化生成 Envoy Filter 的完整过程:Istio 进阶学习系列 - 基于 WebAssembly 实现 Envoy 与 Istio 的功能扩展

未来:一个潜在的技术变革新时代?

WASM 跳出浏览器之后,激发了众多领域产生新的变革,不过就目前来看,WASM 的应用仍然处于起步阶段。一方面,领域的认可度和支持程度仍在不断的完善中,越来越多的语言逐步支持编译到 WASM;另一方面,WASM 自身功能的完善也有很长的路要走,如 WASI、GC、线程支持等。

未来 WASM 是否可以做到像容器一样风靡,达到一个“WASM 原生”时代,还需要时间的证明。下列关于 WASM 最新状况和未来预测的文章,或许从中获取可以找到一些启发。

参考链接