Wasmer 入门指南:基于 WebAssembly 的轻量级容器运行时安装、运行与多语言嵌入实践
【免费下载链接】wasmer🚀 Fast, secure, lightweight containers based on WebAssembly项目地址: https://gitcode.com/gh_mirrors/wa/wasmer
Wasmer 是一个基于 WebAssembly)为主体骨架,结合仓库源码深入讲解 Wasmer 的安装方式、核心特性、CLI 运行与编译命令、WASI 沙箱参数以及多语言嵌入方案,读完你就能在自己的环境中安装 Wasmer、运行.wasm模块,并把它嵌入到 Rust 等应用中。
什么是 Wasmer
根据官方文档定位,Wasmer 是一个"快速且安全"的 WebAssembly 运行时,它的核心目标是把基于 WebAssembly 构建的超轻量级容器(lightweight containers)运行在任何地方:从桌面到云端、边缘节点与 IoT 设备。与传统的操作系统级容器(如 Docker)不同,Wasmer 直接运行 Wasm 字节码,具备更小的体积、更快的启动速度和更严格的默认沙箱。
Wasmer 以单一可执行文件形式提供 CLI,同时也作为库被广泛嵌入到各类编程语言中,本仓库 lib/api、lib/cli 分别对应 Rust 嵌入 API 与命令行工具的实现。
核心特性
官方文档明确列出的特性如下,每一项都可以在仓库源码中找到对应实现:
- 默认安全(secure by default):除非显式开启,否则模块无法访问文件、网络或环境变量。这一"默认拒绝"的沙箱设计在 lib/wasix 的 capabilities 机制中落实,CLI 侧则通过
--volume、--net、--env等参数显式授权。 - 开箱即用地支持 WASI 与 Emscripten:WASI(WebAssembly System Interface)为 Wasm 提供系统调用抽象,Emscripten 产物也可直接运行;仓库中 lib/wasi-types 与 lib/wasix 提供了完整的实现。
- 快:以接近原生(native)的速度执行 WebAssembly。官方文档指出生产环境建议使用 LLVM 编译器以获得最佳运行时性能(详见 lib/api/README.md)。
- 可嵌入多门编程语言:运行时可以作为库被嵌入到 Rust、C/C++、Python、JavaScript、Go、PHP、Ruby、Java 等语言中(下文有完整表格)。
- 遵循最新 WebAssembly 提案:支持 SIMD、Reference Types、Threads 等提案。CLI 中可通过
--enable-simd、--disable-threads、--enable-reference-types等参数控制(见 lib/cli/src/backend.rs)。
安装 Wasmer
官方推荐的安装方式是一行脚本,它提供无依赖的单文件可执行程序:
curl https://get.wasmer.io -sSfL | sh除此之外,官方还提供了多种按环境选择的安装方式:
| 平台 | 包管理器 | 命令 |
|---|---|---|
| Windows | Powershell | iwr https://win.wasmer.io -useb \| iex |
| macOS / Linux | Homebrew | brew install wasmer |
| Windows | Scoop | scoop install wasmer |
| Windows | Chocolatey | choco install wasmer |
| 任意 | Cargo | cargo install wasmer-cli |
其中通过 Cargo 安装时需要注意:CLI 的完整功能由 feature 控制。官方在 lib/cli/README.md 中明确指出,需要手动指定要启用的编译器后端:
cargo install wasmer-cli --features "singlepass,cranelift"或直接在仓库源码目录内构建:
cargo build --release --features "singlepass,cranelift"wasmer-cli支持以下 feature(见 lib/cli/Cargo.toml):wat(执行 WebAssembly 文本格式,默认开启)、wast(运行 wast 测试文件,默认开启)、cache(自动缓存编译产物,默认开启)、wasi(WASI 支持,默认开启)、singlepass、cranelift、llvm(三选一或组合的编译器后端)。默认构建并不包含编译器后端,需要在构建时按需开启。
快速开始:运行 QuickJS
安装完成后即可直接运行编译为 WebAssembly 的 QuickJS(一个可嵌入的小型 JavaScript 引擎)来验证环境:
$ wasmer qjs.wasm QuickJS - Type "\h" for help qjs > const i = 1 + 2; qjs > console.log("hello " + i); hello 3这条命令背后发生了什么?从 lib/cli/src/commands/run/mod.rs 的实现可以看到,wasmer run首先对输入文件做类型探测:.wasm二进制直接读取,.wat文本则通过wat2wasm转换为二进制;随后根据模块使用的 WebAssembly 特性选择兼容的编译器后端创建 Engine,再交给 WASI 运行时执行。对于普通(非 WASI)模块,它会寻找导出的_start函数作为入口(也可用--invoke <name>指定入口函数),并把返回的数值打印到 stdout。
CLI 命令深入:运行与预编译
官方 CLI 文档 lib/cli/README.md 定义了三个核心命令:
查看版本
wasmer -V运行 WebAssembly 文件
wasmer run myfile.wasm预编译 WebAssembly 文件(AOT)
wasmer compile myfile.wasm -o myfile.wasmuwasmu是 "WASM Universal" 的缩写,表示跨平台通用格式的预编译产物。运行预编译文件是最快的方式:
wasmer run myfile.wasmu在 lib/cli/src/commands/compile.rs 中可以看到wasmer compile的实现细节:
- 仅接受 WebAssembly 文件,若输入不是 Wasm 会直接报错(
bail!("wasmer compile only compiles WebAssembly files")); - 通过
--target <TRIPLE>指定编译目标三元组(triple)实现交叉编译,例如在 x86_64 上编译出面向其他架构的产物;Cranelift 编译器要求 SSE2,因此编译目标为 x86_64 时会自动补上SSE2CPU 特性; -m参数可追加 CPU 特性;- 输出文件扩展名如果不是
.wasmu,会给出建议警告; - 编译完成后打印所用编译器与目标信息,并通过
Module::serialize_to_file写出产物(调用链对应 lib/api/src/entities/module 的序列化能力)。
常用运行参数
从 lib/cli/src/commands/run/mod.rs 可以整理出wasmer run的常用参数:
| 参数 | 说明 |
|---|---|
--stack-size <BYTES> | 设置默认栈大小,默认 1048576 字节(1 MiB) |
-e, --entrypoint <NAME> | 指定 webc 包中的入口命令名 |
-i, --invoke <FUNC> | 调用模块导出的指定函数(而非_start) |
--coredump-on-trap <PATH> | 发生 Wasm trap 时在指定路径生成 coredump |
--experimental-napi | 对需要 N-API 导入的模块启用实验性 N-API 运行时 |
--之后的参数 | 透传给被运行模块的命令行参数 |
--invoke特别适合运行函数导出型模块:源码中会先实例化模块,然后按名称查找导出函数,并把命令行参数按函数签名(I32/I64/F32/F64/V128)解析后传入调用,参数个数不匹配时会明确报错。
选择编译器后端
Wasmer 采用可插拔编译器架构,CLI 通过 lib/cli/src/backend.rs 中的RuntimeOptions统一管理。三个编译器的定位(来自 lib/api/README.md):
- Singlepass:编译速度最快,但生成的代码运行时性能未优化,适合对启动延迟极度敏感的场景;
- Cranelift:编译速度与运行时性能的平衡点,适合开发调试;也是 Wasmer 的默认编译器;
- LLVM:生成深度优化的机器码,运行时性能最优,官方建议生产环境使用,可达到接近原生(near-native)的速度。
在 CLI 中分别通过--singlepass、--cranelift、--llvm选择(三者互斥),另有--v8可选用 V8 运行时后端。此外还提供以下与编译相关的选项:
--enable-verifier:开启编译器内部验证;--compiler-debug-dir <DIR>:输出 IR 与目标文件(Cranelift/LLVM/Singlepass 均支持);--compiler-threads <N>:设置编译线程数;--enable-nan-canonicalization:规范化 NaN,保证跨架构的确定性输出;--profiler <perfmap|gdb|lldb>:启用对应性能分析/调试支持;--experimental-artifact:使用实验性产物格式(仅 Linux)。
CLI 还会自动探测 Wasm 模块使用的特性(Features::detect_from_wasm),并在多个后端中过滤出能支持这些特性的引擎;若用户显式指定的后端不支持所需特性,会给出提示建议改用其他后端。特性开关还包括--enable-simd、--disable-threads、--enable-reference-types、--enable-multi-value、--enable-bulk-memory、--enable-tail-call、--enable-memory64、--enable-exceptions、--enable-relaxed-simd以及一键开启全部提案的--enable-all(见 lib/cli/src/backend.rs)。
WASI 沙箱与运行时选项
运行 WASI/WASIX 模块时,wasmer run提供完整的沙箱配置能力。相关参数定义在 lib/cli/src/commands/run/wasi.rs,主要包括:
| 参数 | 说明 |
|---|---|
--volume <HOST_DIR:GUEST_DIR> | 将宿主目录映射到模块内的访客路径;--volume=.表示映射当前目录(不能重复指定) |
--dir/--mapdir | 旧版参数,已废弃,官方提示改用--volume |
--cwd <PATH> | 设置模块初始工作目录(须为绝对路径;对 WASI preview 1 模块无效) |
--env <KEY=VALUE> | 传入自定义环境变量,可多次指定 |
--env-file <PATH> | 从 dotenv 文件批量加载环境变量;显式--env优先级更高(有对应单元测试验证) |
--forward-host-env | 将宿主全部环境变量透传给访客 |
--net[=RULESET] | 开启网络能力;可附加规则集,如dns:allow=example.com:80、dns:deny=*danger.xyz:*、ipv4:allow=127.0.0.1:80/in |
--http-client | 允许实例发送 HTTP 请求(默认允许所有域名) |
--enable-async-threads/--enable-cpu-backoff | 异步线程与 CPU 指数退避控制 |
--no-tty | 禁用 TTY 桥接 |
--deny-multiple-wasi-versions | 要求模块只导入单一版本的 WASI |
--disable-cache | 关闭编译产物缓存(默认启用,缓存可显著加速模块加载) |
--use <PKG> | 注入依赖的容器包 |
--include-webc <WEBC> | 显式包含本地.webc包或按namespace/name/version.webc布局的本地 registry 目录 |
--offline | 仅从本地源解析,不访问在线 registry |
--map-command <ALIAS=HOST_PATH> | 把宿主命令以别名映射给访客调用 |
网络方面,未显式指定--net时,CLI 会使用"询问式"网络实现(AskingNetworking),结合包能力缓存决定是否放行;指定规则集时则通过 lib/virtual-net 的Ruleset做细粒度过滤。文件系统方面,--volume的挂载基于 lib/virtual-fs 的MountFileSystem与OverlayFileSystem实现,访客根目录为虚拟根文件系统,未映射的宿主路径一律不可见。
此外,CLI 默认开启编译产物缓存(存于用户缓存目录的compiled子目录),采用内存缓存加文件系统缓存(FileSystemCache)的二级结构,首次编译后再次运行同一模块可跳过编译、直接加载缓存产物。
把 Wasmer 嵌入到你的程序里
除了 CLI,Wasmer 运行时还能以库的形式嵌入到多种语言中。官方文档给出的语言集成总览如下(括号内为官方提供的包名,均在各自生态的官方渠道发布):
| 语言 | 包 |
|---|---|
| Rust | wasmer(crates.io) |
| C/C++ | wasm.h/wasm.hh头文件(lib/c-api) |
| C# | WasmerSharp(NuGet) |
| D | wasmer(Dub) |
| Python | wasmer(PyPI) |
| JavaScript | @wasmerio(NPM) |
| Go | wasmer(Go 模块) |
| PHP | wasm(PECL) |
| Ruby | wasmer(RubyGems) |
| Java | wasmer/wasmer-jni |
| Elixir | wasmex(hex) |
| OCaml | wasmer(opam) |
| Dart | wasm(pub) |
| R / Postgres / Swift / Zig / Lisp | 官方暂无发布包 |
其中 Rust 是官方原生实现,仓库 examples/hello_world.rs 提供了一个最小可运行的嵌入示例,演示了完整的"编译 → 实例化 → 导入 → 调用"链路:
use wasmer::{Function, Instance, Module, Store, TypedFunction, imports, wat2wasm}; fn main() -> anyhow::Result<()> { // 使用 WAT 文本格式描述一个导入 say_hello 并导出 run 的模块 let wasm_bytes = wat2wasm( br#" (module (type $no_args_no_rets_t (func (param) (result))) (import "env" "say_hello" (func $say_hello (type $no_args_no_rets_t))) (func $run (type $no_args_no_rets_t) (call $say_hello)) (export "run" (func $run))) "#, )?; let mut store = Store::default(); let module = Module::new(&store, wasm_bytes)?; // 用宿主函数满足模块的导入 fn say_hello_world() { println!("Hello, world!") } let import_object = imports! { "env" => { "say_hello" => Function::new_typed(&mut store, say_hello_world), } }; let instance = Instance::new(&mut store, &module, &import_object)?; let run_func: TypedFunction<(), ()> = instance.exports.get_typed_function(&store, "run")?; run_func.call(&mut store)?; Ok(()) }运行方式(需在仓库根目录,并开启任一编译器后端):
cargo run --example hello-world --release --features "cranelift"lib/api/README.md还介绍了 Rust API 的进阶能力:
- Headless 模式:模块编译并序列化后,可以脱离编译器仅用 VM 加载执行(headless),加载更快、体积更小,适合资源受限环境;
- 交叉编译:大多数编译器支持针对不同架构/平台预编译并序列化 Wasm 模块,之后再在目标平台上运行;
- JavaScript 环境:开启
jsCargo feature 后,用 Wasmer 编写的 Rust 程序可编译成 Wasm,运行在浏览器、Node.js、Deno 等 JavaScript 环境中(此时直接使用宿主环境的引擎)。
结语与进一步探索
本文围绕 docs/ko/README.md 的官方介绍,完整梳理了 Wasmer 的定位、特性、全部安装方式、QuickJS 快速上手、CLI 运行与 AOT 编译、编译器后端选择、WASI 沙箱参数以及多语言嵌入方案。如果你希望进一步深入:
- 了解 CLI 完整命令与 feature 配置:lib/cli/README.md;
- 从源码构建 Wasmer:docs/BUILD.md;
- 运行官方测试套件:docs/TEST.md;
- 可运行的嵌入示例:examples,如 imports_function.rs、memory.rs、wasi.rs;
- 深入运行时内核实现:lib/wasix、lib/vm、lib/compiler-cranelift、lib/compiler-llvm、lib/compiler-singlepass。
从"一行命令运行 QuickJS"到"把 Wasm 嵌入 Rust 应用",Wasmer 提供了一条从轻量容器到嵌入式运行时都适用的 WebAssembly 落地路径。
【免费下载链接】wasmer🚀 Fast, secure, lightweight containers based on WebAssembly项目地址: https://gitcode.com/gh_mirrors/wa/wasmer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考