# Higress Rust Wasm 插件开发框架 ## 介绍 此 SDK 用于使用 Rust 语言开发 Higress 的 Wasm 插件。基于 [proxy-wasm-rust-sdk](https://github.com/higress-group/proxy-wasm-rust-sdk) 构建,提供了丰富的开发工具和示例。 ## 特性 - 🚀 **高性能**: 基于 Rust 和 WebAssembly,提供接近原生的性能 - 🛠️ **易开发**: 提供完整的开发框架和丰富的示例 - 🔧 **可扩展**: 支持自定义配置、规则匹配、HTTP 调用等功能 - 📦 **容器化**: 支持 Docker 构建和 OCI 镜像发布 - 🧪 **测试友好**: 内置测试框架和 lint 工具 ## 快速开始 ### 环境要求 - Rust 1.80+ - Docker - Make - WASI 目标支持:`rustup target add wasm32-wasip1` **重要提示**:确保使用 rustup 管理的 Rust 工具链,避免与 Homebrew 安装的 Rust 冲突。如果遇到 WASI 目标问题,请确保: 1. **使用 rustup 管理 Rust**: ```bash # 安装 rustup(如果还没有) curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # 安装 WASI 目标 rustup target add wasm32-wasip1 ``` 2. **确保 shell 配置正确**: ```bash # 检查 ~/.zshrc 或 ~/.bashrc 是否包含 source "$HOME/.cargo/env" ``` ### 构建插件 **执行路径**: 在 `plugins/wasm-rust/` 目录下执行 ```bash # 进入项目目录 cd plugins/wasm-rust/ # 构建默认插件 (say-hello) make build # 构建指定插件 make build PLUGIN_NAME=say-hello # 构建并指定版本 make build PLUGIN_NAME=say-hello PLUGIN_VERSION=1.0.0 # 注意:由于 Makefile 中的 .DEFAULT 目标,需要明确指定目标 # 如果遇到 "Nothing to be done" 错误,请确保使用正确的语法 ``` **重要提示**: - 某些插件(如 `ai-data-masking`)依赖 C 库,可能需要额外的配置才能成功构建 - 建议先使用简单的插件(如 `say-hello`)测试构建环境 - 构建成功后会生成 `extensions//plugin.wasm` 文件 ### 运行测试 **执行路径**: 在 `plugins/wasm-rust/` 目录下执行 ```bash # 进入项目目录 cd plugins/wasm-rust/ # 运行所有测试 make test-base # 运行指定插件测试 make test PLUGIN_NAME=say-hello ``` ### 代码检查 **执行路径**: 在 `plugins/wasm-rust/` 目录下执行 ```bash # 进入项目目录 cd plugins/wasm-rust/ # 运行所有 lint 检查 make lint-base # 运行指定插件 lint 检查 make lint PLUGIN_NAME=say-hello ``` ### Makefile 说明 当前 Makefile 包含以下可用目标: - `build` - 构建插件(默认插件为 say-hello) - `build-image` - 构建插件对应镜像(默认插件为 say-hello) - `lint-base` - 对所有代码进行 lint 检查 - `lint` - 对指定插件进行 lint 检查 - `test-base` - 运行所有测试 - `test` - 运行指定插件测试 - `builder` - 构建构建器镜像 **重要提示**:Makefile 中的 `.DEFAULT:` 目标可能会影响某些命令的执行。如果遇到 "Nothing to be done" 错误,请确保: 1. 正确指定了目标名称(如 `build`、`lint`、`test`) 2. 使用了正确的参数格式 3. 插件目录存在且包含有效的 Cargo.toml 文件 ## 插件开发 ### 项目结构 ``` wasm-rust/ ├── src/ # SDK 核心代码 │ ├── cluster_wrapper.rs # 集群包装器 │ ├── error.rs # 错误处理 │ ├── event_stream.rs # 事件流处理 │ ├── internal.rs # 内部 API │ ├── log.rs # 日志系统 │ ├── plugin_wrapper.rs # 插件包装器 │ ├── redis_wrapper.rs # Redis 包装器 │ ├── request_wrapper.rs # 请求包装器 │ └── rule_matcher.rs # 规则匹配器 ├── extensions/ # 插件示例 │ ├── say-hello/ # 基础示例 │ ├── ai-data-masking/ # AI 数据脱敏 │ ├── request-block/ # 请求拦截 │ ├── ai-intent/ # AI 意图识别 │ └── demo-wasm/ # 演示插件 ├── example/ # 完整示例 │ ├── wrapper-say-hello/ # 包装器示例 │ └── sse-timing/ # SSE 时序示例 └── Makefile # 构建脚本 ``` ### 创建新插件 **执行路径**: 在 `plugins/wasm-rust/` 目录下执行 1. **创建插件目录** ```bash # 进入项目目录 cd plugins/wasm-rust/ # 创建插件目录 mkdir extensions/my-plugin cd extensions/my-plugin ``` 2. **创建 Cargo.toml** ```toml [package] name = "my-plugin" version = "0.1.0" edition = "2021" publish = false [lib] crate-type = ["cdylib"] [dependencies] higress-wasm-rust = { path = "../../", version = "0.1.0" } proxy-wasm = { git="https://github.com/higress-group/proxy-wasm-rust-sdk", branch="main", version="0.2.2" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" ``` 3. **创建插件代码** ```rust use higress_wasm_rust::*; use proxy_wasm::traits::*; use proxy_wasm::types::*; use serde::{Deserialize, Serialize}; #[derive(Default, Clone, Serialize, Deserialize)] struct MyPluginConfig { name: String, } struct MyPluginRoot { log: Log, rule_matcher: SharedRuleMatcher, } impl MyPluginRoot { fn new() -> Self { Self { log: Log::new("my-plugin".to_string()), rule_matcher: Rc::new(RefCell::new(RuleMatcher::new())), } } } impl Context for MyPluginRoot {} impl RootContext for MyPluginRoot { fn on_configure(&mut self, plugin_configuration_size: usize) -> bool { on_configure(self, plugin_configuration_size, &mut self.rule_matcher.borrow_mut(), &self.log) } fn create_http_context(&self, context_id: u32) -> Option> { Some(Box::new(MyPlugin { log: self.log.clone(), rule_matcher: self.rule_matcher.clone(), })) } fn get_type(&self) -> Option { Some(ContextType::HttpFilter) } } struct MyPlugin { log: Log, rule_matcher: SharedRuleMatcher, } impl Context for MyPlugin {} impl HttpContext for MyPlugin { fn on_http_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> HeaderAction { self.log.info("Processing request headers"); HeaderAction::Continue } } proxy_wasm::main! {|_| -> Box { Box::new(MyPluginRoot::new()) }} ``` ### 插件配置 插件支持全局配置和规则配置: ```yaml apiVersion: extensions.higress.io/v1alpha1 kind: WasmPlugin metadata: name: my-plugin namespace: higress-system spec: selector: matchLabels: higress: higress-system-higress-gateway defaultConfig: name: "default" url: oci://higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/my-plugin:1.0.0 rules: - match: - route: - "my-route" config: name: "route-specific" ``` ## 内置插件 ### 基础插件 - **say-hello**: 基础示例插件,演示插件开发流程 ✅ - **demo-wasm**: 完整演示插件,包含 Redis 集成等功能 ### 功能插件 - **ai-data-masking**: AI 数据脱敏插件 ⚠️ - 支持敏感词拦截和替换 - 支持 OpenAI 协议和自定义 JSONPath - 内置敏感词库和自定义规则 - **注意**: 依赖 C 库,可能需要额外配置 - **request-block**: 请求拦截插件 ✅ - 支持 URL、Header、Body 拦截 - 支持正则表达式匹配 - 可配置拦截状态码和消息 - **ai-intent**: AI 意图识别插件 - 支持 LLM 调用和意图分类 - 可配置代理服务和模型参数 **构建状态说明**: - ✅ 已验证可成功构建 - ⚠️ 可能需要额外配置 - 未标记的插件需要进一步测试 ### 故障排除 **问题**: `error[E0463]: can't find crate for 'core'` **原因**: 系统中有多个 Rust 安装,Homebrew 的 Rust 优先于 rustup 的 Rust **解决方案**: ```bash # 移除 Homebrew 的 Rust brew uninstall rust # 确保使用 rustup 的 Rust rustup default nightly rustup target add wasm32-wasip1 # 确保 shell 配置正确 echo 'source "$HOME/.cargo/env"' >> ~/.zshrc source ~/.zshrc ``` ## 构建和部署 ### 本地构建 **执行路径**: 在 `plugins/wasm-rust/` 目录下执行 ```bash # 进入项目目录 cd plugins/wasm-rust/ # 使用 Makefile 构建插件(推荐) make build PLUGIN_NAME=my-plugin # 直接使用 Cargo 构建 WASM 文件 cd extensions/my-plugin cargo build --target wasm32-wasip1 --release # 构建 Docker 镜像 cd plugins/wasm-rust/ docker build -t my-plugin:latest --build-arg PLUGIN_NAME=my-plugin . ``` ```` ### Docker 构建说明 **重要提示**:Dockerfile 需要指定 `PLUGIN_NAME` 参数来构建特定插件。 ```bash # 构建 say-hello 插件 docker build -t say-hello:latest --build-arg PLUGIN_NAME=say-hello . # 构建 ai-data-masking 插件 docker build -t ai-data-masking:latest --build-arg PLUGIN_NAME=ai-data-masking . # 构建 request-block 插件 docker build -t request-block:latest --build-arg PLUGIN_NAME=request-block . # 构建自定义插件 docker build -t my-custom-plugin:latest --build-arg PLUGIN_NAME=my-custom-plugin . ``` **插件分发特性**: - 遵循OCI镜像规范的插件分发,可以参考[OCI镜像规范](https://github.com/opencontainers/image-spec/blob/main/image-layout.md) - 基于 `rust:1.80` 构建环境 - 自动安装 WASI 目标 - 多阶段构建,最终镜像基于 `scratch` - 最小化镜像大小(约 300-400KB) - 只包含编译后的 WASM 文件 **常见问题**: - **错误**: `failed to read dockerfile: open Dockerfile: no such file or directory` - **解决**: 确保在 `plugins/wasm-rust/` 目录下执行命令 - **错误**: `failed to solve: failed to compute cache key` - **解决**: 确保指定了正确的 `PLUGIN_NAME` 参数 - **错误**: `can't find crate for 'core'` - **解决**: Docker 构建环境会自动安装 WASI 目标,无需手动配置 ### 发布到镜像仓库 **执行路径**: 在 `plugins/wasm-rust/` 目录下执行 ```bash # 进入项目目录 cd plugins/wasm-rust/ # 构建插件 make build PLUGIN_NAME=my-plugin PLUGIN_VERSION=1.0.0 # 构建构建器镜像 make builder ```` ### 在 Higress 中使用 ```yaml apiVersion: extensions.higress.io/v1alpha1 kind: WasmPlugin metadata: name: my-plugin namespace: higress-system spec: selector: matchLabels: higress: higress-system-higress-gateway defaultConfig: # 插件配置 url: oci://higress-registry.cn-hangzhou.cr.aliyuncs.com/plugins/my-plugin:1.0.0 ``` ## 开发工具 ### 路径说明 不同命令需要在不同的目录下执行: - **Makefile 命令**(如 `make build`、`make build-image`、`make test`、`make lint`):在 `plugins/wasm-rust/` 目录下执行 - **Cargo 命令**(如 `cargo build`、`cargo test`):在具体的插件目录下执行(如 `plugins/wasm-rust/extensions/my-plugin/`) - **Docker 命令**:在 `plugins/wasm-rust/` 目录下执行,需要指定 `PLUGIN_NAME` 参数 ### 调试 插件支持详细的日志输出: ```rust self.log.info("Processing request"); self.log.debugf(format_args!("Request headers: {:?}", headers)); self.log.error("Error occurred"); ``` ### 测试 **执行路径**: 在插件目录下执行(如 `plugins/wasm-rust/extensions/my-plugin/`) ```bash # 进入插件目录 cd plugins/wasm-rust/extensions/my-plugin/ # 运行单元测试 cargo test # 运行集成测试 cargo test --test integration ``` ### 性能优化 - 使用 `--release` 模式构建 - 避免不必要的内存分配 - 合理使用缓存机制 ## 贡献指南 1. Fork 项目 2. 创建功能分支 3. 提交代码变更 4. 运行测试和 lint 检查 5. 提交 Pull Request ## 相关链接 - [Higress 官方文档](https://higress.io/) - [proxy-wasm-rust-sdk](https://github.com/higress-group/proxy-wasm-rust-sdk) - [WebAssembly 规范](https://webassembly.org/) - [Rust 官方文档](https://doc.rust-lang.org/) ## 许可证 本项目采用 Apache 2.0 许可证。