点赞
评论
收藏
分享
举报
WebAssembly 组件模型 — 原因、方法和内容(第 2 部分)
发表于2025-03-26 17:41

浏览 2.2k

原文作者:Timo Stark - F5 专业服务工程师
原文链接:WebAssembly 组件模型 — 原因、方法和内容(第 2 部分)
转载来源: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 相关的技术干货、互动问答、系列课程、活动资源: 开源社区官网 | 微信公众号 | B 站


已修改于2025-03-26 17:41
本作品系原创
创作不易,留下一份鼓励
NGINX官方账号

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
NGINX官方账号
这家伙很懒还未留下介绍~
331
文章
21
问答
201
粉丝
相关文章
介绍nginx网页配置工具QQ技术交流群1:1106758598QQ技术交流群2:560797506邮箱: cym1102@qq.com官网地址: http://www.nginxwebui.cn码云: https://gitee.com/cym1102/nginxWebUIgithub: https://github.com/cym1102/nginxWebUI功能特点nginxWebUI也可管理多个nginx服务器集群,随时一键切换到对应服务器上进行nginx配置,也可以一键将某台服务器配置同步到其他服务器,方便集群管理.部署此项目后,配置nginx再也不用上网各种搜索配置代码,再也不用手动申请和配置ssl证书,只需要在本项目中进行增删改查就可方便的配置和启动nginx。技术说明本项目是基于springBoot的web系统,数据库使用sqlite,因此服务器上不需要安装任何数据库项目启动时会释放一个.sqlite.db到系统用户文件夹中,注意进行备份本系统通过Let'sencrypt申请证书,使用acme.sh脚本
点赞 6
浏览 23.4k
  前三周学习了陶辉老师的“NGINX基础培训系列课程”,感觉受益良多,在这里想把一些知识点记录一下,和大家分享一下知识点,也方便日后的随手查看,温故知新。  首先,我们了解到了Nginx的版本,Nginx发布版本分为主线版本和稳定版本,区分两个版本也非常简单,主线版本版本号为单数,比如1.19,稳定版本为双数,比如1.18,今天我要说的是稳定版本,这个版本会尽量少的减少Nginx的bug问题,适用于生产环境,这里我不建议使用Nginx和其他软件一样在生产环境中落后一个或多个大版本使用,之前生产环境做过漏扫,发现我们编译自带的Nginx版本为:nginx/1.13.3(查询命令为nginx-V),结果出现了多个漏洞,四个高危和一个中危漏洞:        通过升级Nginx到稳定版最新版本后修复!  其次,是Nginx发行版本的选择,目前比较流行的有:nginx、nginxplus、Tengine、openresty、ope
点赞 1
浏览 16.8k
感谢您参加“NGINX从入门到精通进阶系列培训”!以下为培训的问答、课件和录像,希望您能通过此培训学有所得,祝学习进步!>问与答:- 基础篇+高级篇 - 应用篇+实战篇(New)>课件(PPT):基础篇:-NGINX概要、安装、配置:https://interact.f5.com/rs/653-SMC-783/images/CNFEB22-NginxCoreCourse-Setup.pdf-NGINX日志、运维:https://interact.f5.com/rs/653-SMC-783/images/cnfeb22-nginxcorecourse-maintenance.pdf高级篇:-NGINX变量、API:https://interact.f5.com/rs/653-SMC-783/images/CNFEB22-NginxCoreCourse-API.pdf-NGINXSSL、NJS:https://interact.f5.com/rs/653-SMC-783/images/CNFEB22-NginxCoreCourse-SSL.pdf
点赞 10
浏览 19.3k