您现在的位置是:首页 > 文章详情

WebAssembly 组件模型 — 原因、方法和内容(第 2 部分)

日期:2025-05-07点击:25
原文作者:Timo Stark - F5 专业服务工程师
转载来源: NGINX 中文官网

NGINX 唯一中文官方社区 ,尽在 nginx.org.cn
 
 
本文是关于 Wasm 组件模型、其生态系统及如何在 NGINX Unit 中使用 Wasm 组件的系列博文的第二篇。在 第一篇 中,我们介绍了所有概念部分。本文将重点介绍 Wasm 组件创建流程。
 

基于 Rust 的 Wasm 组件教程

Rust 是首选 WebAssembly 开发语言,在支持方面也最为成熟。在本示例中,我们将使用 Rust 及其生态系统创建一个可直接托管在 NGINX Unit 上的 Wasm 组件。
 
本教程适用于基于 Linux 的操作系统和 MacOS。如果您使用的是 Windows 系统,建议您使用 WSL2 (Windows Subsystem for Linux) 进行操作。如果您尚未安装 NGINX Unit 和 WebAssembly 语言模块,请使用官方 Docker 镜像 unit:wasm 进行安装。
 

Rust 开发设置

若无 Rust 生态系统,请先安装。截至本文撰写之时,Rust 1.76 是最新的稳定版本。如需安装 Rust,请参阅其网站上的说明。
 
安装完成后,可通过运行以下命令来确认 Rust 的当前版本:
 
$ rustc -V rustc 1.76.0 (07dca489a 2024-02-04)
 
要创建 Wasm 组件,我们需要一些额外的工具。这是一次性设置,支持您编写 Rust 源代码并将其编译为 Wasm 组件。
  

添加 wasm32-wasi 编译器目标

wasm32-wasi 编译器目标将为 rustc 安装提供一般 Wasm 支持。运行以下命令添加目标:
 
$ rustup target add wasm32-wasi

 

安装 cargo-component

cargo-component 将添加一个 cargo 子命令,以便在 Rust 项目中构建 Wasm 组件,而无需任何中间步骤。若要安装最新版本,请运行以下命令:
 
$ cargo install cargo-component

 

安装 wasmtime 运行时和 CLI 进行测试

wasmtime-cli 将用于测试和使用 Wasm 组件。截至本文撰写之时,我们使用的是 Wasmtime 18。若要安装最新版本的 Wasmtime,请运行以下命令:
 
$ curl https://wasmtime.dev/install.sh -sSf | bash
准备好所有工具后,我们就可以创建 Rust 项目了。
 

使用 wasi Rust 库

WASI Rust 官方库的使用体验很有意思。组件构建时间极短,而且库的依赖项占用空间非常小。不过,这在开发人员体验方面带来了一定的代价。亲自体验一下:
 
首先使用 cargo component 新建一个 Wasm 组件:
 
$ cargo component new --lib test-wasi-component
导航到 test-wasi-component 目录。
 
添加 wasi crate:
 
$ cargo add wasi
 
接下来,使用所选的文本编辑器修改 Cargo.toml 文件。将 proxy = true 配置添加到 [package.metadata.component] 部分。保存更改后,您的 Cargo.toml 文件应如下所示:
 
[package] name = "test-wasi-component" version = "0.1.0" edition = "2021" [dependencies] bitflags = "2.4.2" wit-bindgen-rt = "0.21.0" wasi = "0.13.0" [lib] crate-type = ["cdylib"] [package.metadata.component] package = "component:test-wasi-component" proxy = true [package.metadata.component.dependencies]
 
src/lib.rs 中的实际代码应如下所示:
 
use wasi::http::types::{ Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam, }; wasi::http::proxy::export!(Component); struct Component; impl wasi::exports::http::incoming_handler::Guest for Component { fn handle(_request: IncomingRequest, response_out: ResponseOutparam) { let hdrs = Fields::new(); let mesg = String::from("Hello, This is a Wasm Component using wasi/http:proxy!"); let _try = hdrs.set(&"Content-Type".to_string(), &[b"plain/text".to_vec()]); let _try = hdrs.set(&"Content-Length".to_string(), &[mesg.len().to_string().as_bytes().to_vec()]); let resp = OutgoingResponse::new(hdrs); // 添加 HTTP 响应状态代码 resp.set_status_code(200).unwrap(); let body = resp.body().unwrap(); ResponseOutparam::set(response_out, Ok(resp)); let out = body.write().unwrap(); out.blocking_write_and_flush(mesg.as_bytes()).unwrap(); drop(out); OutgoingBody::finish(body, None).unwrap(); } }
 
要使用 wasi crate,我们需要做一些简单的 Rust 操作。这些操作并不麻烦,但您在选择此选项时需要稍加考虑。对于 wasi:http/proxy world,GitHub 上有一个接口说明,有助于您编写代码。
 
下面来构建组件。从 test-wasi-component 目录运行以下命令:
 
$ cargo component build --release
该 build 显示,依赖项占用空间非常小,这也是 wasi crate 的一大优势。
 
若要测试组件,我们可以使用 wasmtime serve。
 
$ wasmtime serve target/wasm32-wasi/release/test_wasi_component.wasm
输出结果应为:
 
$ wasmtime serve target/wasm32-wasi/release/test_wasi_component.wasm Serving HTTP on http://0.0.0.0:8080/
 
向公开的端点发送请求,输出结果将如下所示:
 
$ curl -v localhost:8080 … > GET / HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/8.4.0 > Accept: */* > < HTTP/1.1 200 OK < content-type: plain/text < content-length: 54 < date: Tue, 12 Mar 2024 12:28:56 GMT < * Connection #0 to host localhost left intact Hello, This is a Wasm Component using wasi/http:proxy!
 

适用于生产级 Wasm 工作负载的 NGINX Unit

虽然 wasmtime-cli 接口非常适合在本地测试 Wasm 组件,但生产工作负载有着更高的要求。
 
有了 NGINX Unit Wasm 运行时,您就能在单个主机上运行 Wasm 工作负载及其他主机应用,并利用其他所有强大的 Unit 功能。考虑到 Unit 的设计,而且我们已将监听器与应用运行时解耦,您可在与 Wasm 组件共享请求或将 HTTPS 添加到堆栈之前,充分利用 Unit 路由器做出路由决策。
 
要在 NGINX Unit 上运行该组件,启动 Unit 并发送初始配置,确保使用绝对路径指向 Wasm 组件。
 
创建 config.json 文件:
 
{ "listeners": { "127.0.0.1:8085": { "pass": "applications/my-wasm-component" } }, "applications": { "my-wasm-component": { "type": "wasm-wasi-component", "component": "path/target/wasm32-wasi/release/test_wasi_component.wasm" } } }
 
使用 unitc 应用配置:
 
$ unitc config.json /config
 
向公开的端点发送请求,不同的运行时实现将输出相同的内容:
 
$ curl -v localhost:8085 … < HTTP/1.1 200 OK < content-type: plain/text < content-length: 54 < Server: Unit/1.32.0 < Date: Tue, 12 Mar 2024 15:16:13 GMT < * Connection #0 to host localhost left intact Hello, This is a Wasm Component using wasi/http:proxy!
 
这就是 Wasm 组件的优势所在。您只需构建一次,即可在所有运行时运行。
  

后续

Wasm 生态系统及其所有相关项目正快速成长和推进。每周都会推出新功能和新想法。NGINX Unit 对 Wasm 的支持从未改变,并将继续在我们的 Wasmtime 集成中实现新功能,同时发布有关 Wasm 的技术博文。
  

NGINX 唯一中文官方社区 ,尽在 nginx.org.cn
更多 NGINX 相关的技术干货、互动问答、系列课程、活动资源: 开源社区官网 | 微信公众号
原文链接:https://my.oschina.net/u/5246775/blog/18333205
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章