Higress wasm-go 插件开发指南:从 SDK 构建、部署到测试的完整实践

发布时间:2026/11/11 20:47:30

Higress wasm-go 插件开发指南:从 SDK 构建、部署到测试的完整实践 Higress wasm-go 插件开发指南从 SDK 构建、部署到测试的完整实践【免费下载链接】higress AI Gateway | AI Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/hi/higress本篇技术指南以 Higress 官方的 wasm-go SDK 文档为核心系统讲解如何使用 Go 语言为 Higress 开发 WebAssemblyWASM插件涵盖基于 Higress wasm-go builder 的一键构建、本地手工编译与镜像推送、通过WasmPluginCRD 让插件在全局/路由级/域名级生效以及单元测试与 E2E 测试的完整编写与运行流程。读完本文你将掌握从零编写一个可运行的 Higress Go WASM 插件以 request-block 参考插件为例所需的全部技能。一、wasm-go SDK 与插件运行机制概览Higress 的 wasm-go SDK 用于使用 Go 语言开发 Higress 的 WASM 插件。插件以plugin.wasm的形态被加载到 Envoy/Higress 网关的 WASM 运行时中通过 proxy-wasm ABI 与网关进行交互。其核心依赖为github.com/higress-group/proxy-wasm-go-sdk参考插件 request-block 的 go.mod 中同时依赖该 SDK 与github.com/higress-group/wasm-go封装库Go 版本要求为 1.24。从参考插件 plugins/wasm-go/examples/request-block/main.go 的源码结构可以清晰看到 SDK 的标准用法func init() { wrapper.SetCtx( request-block, wrapper.ParseConfigBy(parseConfig), wrapper.ProcessRequestHeadersBy(onHttpRequestHeaders), wrapper.ProcessRequestBodyBy(onHttpRequestBody), ) }插件通过init()注册插件名称、配置解析函数以及请求头/请求体处理函数parseConfig负责把 WasmPlugin 的defaultConfigJSON 解析为结构体onHttpRequestHeaders与onHttpRequestBody分别在请求头与请求体阶段执行拦截逻辑命中规则后调用proxywasm.SendHttpResponseWithDetail直接返回阻断响应。此外文档还提到一个特殊场景mcp-server插件的 MCP2026-07-28一致性验证有独立的构建入口该入口不依赖批量构建器仅扫描VERSION以-alpha结尾插件的规则可直接执行make build-mcp-server-wasmplugin cd plugins/wasm-go/extensions/mcp-server ./testdata/interop/run.sh其互操作测试固定锁定官方 Go SDKv1.7.0与 TypeScript Client2.0.0分别要求 Go 1.25 与 Node.js 20详见 mcp-server 文档。二、使用 Higress wasm-go builder 快速构建wasm-go 插件可以使用 Higress 提供的构建器镜像一键构建。执行以下命令即可构建参考插件 request-block# NOTE: 如果想在构建插件时设置额外的构建参数 EXTRA_TAGS # 请更新 ${PLUGIN_ROOT}/${PLUGIN_NAME} 插件目录下对应的 .buildrc 文件 # NOTE: 如果想自定义最终推送的镜像短名覆盖默认的插件目录名 # 可以在 .buildrc 中添加 IMAGE_NAMEyour-image-name。 # 镜像短名只能包含小写字母、数字、.、_、-否则构建会失败。 # 本设置仅影响推送的镜像 tag不影响源码路径。 $ PLUGIN_ROOTexamples PLUGIN_NAMErequest-block make build构建输出大致如下DOCKER_BUILDKIT1 docker build --build-arg PLUGIN_ROOTexamples --build-arg PLUGIN_NAMErequest-block \ -t request-block:20230223-173305-3b1a471 \ --output examples/request-block . [] Building 67.7s (12/12) FINISHED image: request-block:20230223-173305-3b1a471 output wasm file: examples/request-block/plugin.wasm该命令最终构建出一个 wasm 文件和一个 Docker 镜像。本地的plugin.wasm文件会被输出到对应插件的目录下如上例为examples/request-block/plugin.wasm可直接用于本地调试。如果想在构建的同时推送镜像可以直接使用make build-push。构建参数说明参数名称可选/必须默认值含义PLUGIN_NAME可选hello-world要构建的插件名称PLUGIN_ROOT可选extensions插件所在的根目录构建参考插件时设为examplesREGISTRY可选空生成的镜像的仓库地址如example.registry.io/my-name/。注意REGISTRY值应当以/结尾IMG可选如不设置则根据仓库地址、插件名称、构建时间以及 git commit id 生成生成的镜像名称如非空则会覆盖REGISTRY参数这些参数与 plugins/wasm-go/Makefile 中的定义一一对应PLUGIN_NAME ? hello-world、PLUGIN_ROOT ? extensions镜像 tag 由构建时间BUILD_TIME格式YYYYMMDD-HHMMSS与 git commit idCOMMIT_ID取git rev-parse --short HEAD拼接而成例如20230223-173305-3b1a471IMG ? ${REGISTRY}${PLUGIN_NAME}:${IMAGE_TAG}即为最终镜像名。构建器镜像默认使用wasm-go-builder:go1.24.4-oras1.0.0对应 Makefile 中的GO_VERSION ? 1.24.4、ORAS_VERSION ? 1.0.0构建时会通过--output参数把产物目录挂出到宿主机。构建器镜像的底层逻辑见 plugins/wasm-go/Dockerfile它先从wasm-go-builder基础镜像中复制 Go 工具链与 ORAS 工具然后在/workspace/$PLUGIN_ROOT/$PLUGIN_NAME目录下执行go mod tidy、可选执行prepare.sh最终以GOOSwasip1 GOARCHwasm go build -buildmodec-shared -o /main.wasm .编译出 WASM 产物并放入FROM scratch的最终镜像中重命名为plugin.wasm。而构建器镜像本身plugins/wasm-go/DockerfileBuilder则负责下载指定版本的 Go 与 ORAS 二进制支持 amd64 / arm64 双架构。三、本地构建 wasm 并推送镜像如果不想依赖云端构建器也可以先在本地把 wasm 编译出来再拷贝到 Docker 镜像中。本地编译环境要求Go 版本 1.24需要支持 wasm 构建特性下面是本地多步骤构建 request-block 参考插件的完整示例。step1. 编译 wasmGOOSwasip1 GOARCHwasm go build -buildmodec-shared -o ./examples/request-block/main.wasm ./examples/request-block这里使用了 Go 的 WASI 编译目标wasip1并指定-buildmodec-shared以生成可被 WASM 运行时加载的动态库格式产物main.wasm。这一命令与 plugins/wasm-go/Makefile 中local-build目标的逻辑一致只是后者还支持在执行编译前先运行插件目录下可选的prepare.sh脚本。如果需要更复杂的 Header 状态管理等高级用法可进一步查阅 Higress 官方文档中关于 Go 开发插件的最佳实践章节。step2. 构建并推送插件的 Docker 镜像使用这份简单的 DockerfileFROM scratch COPY main.wasm plugin.wasmdocker build -t your_registry_hub/request-block:2.0.0 -f your_dockerfile . docker push your_registry_hub/request-block:2.0.0FROM scratch意味着最终镜像仅包含一个plugin.wasm文件体积极小Higress 网关运行时只关心镜像内的plugin.wasm文件并将其加载进 WASM 虚拟机执行。推送完成后该镜像地址就是后续 WasmPlugin 资源中url字段的取值。四、创建 WasmPlugin 资源使插件生效编译并推送好镜像后通过创建 WasmPlugin 自定义资源即可让插件在网关中生效。WasmPlugin 的完整字段语义可以参考 Istio 官方 WasmPlugin API 文档文档中提及apiVersion: extensions.higress.io/v1alpha1这是 Higress 在 Istio WasmPlugin 基础上的扩展 CRD。编写 WasmPlugin 资源如下apiVersion: extensions.higress.io/v1alpha1 kind: WasmPlugin metadata: name: request-block namespace: higress-system spec: defaultConfig: block_urls: - swagger.html url: oci://your_registry_hub/request-block:2.0.0 # 之前构建和推送的 image 地址使用kubectl apply -f your-wasm-plugin-yaml使资源生效。资源生效后如果请求 url 携带swagger.html则该请求会被拒绝例如curl your_gateway_address/api/user/swagger.html返回结果HTTP/1.1 403 Forbidden date: Wed, 09 Nov 2022 12:12:32 GMT server: istio-envoy content-length: 0这里defaultConfig中的block_urls就是 main.go 中parseConfig解析的第一个配置项插件把block_urls中声明的关键字swagger.html与请求路径:path做包含匹配strings.Contains命中即返回 403。除block_urls外request-block 插件还支持更多配置项均可在defaultConfig中使用配置项含义block_urls请求路径包含指定关键字即拦截block_exact_urls请求路径精确等于指定值即拦截block_regexp_urls请求路径匹配指定正则即拦截block_headers请求头包含指定关键字即拦截block_bodies请求体包含指定关键字即拦截blocked_code拦截响应状态码默认 403仅接受 100~599 的合法状态码否则回退 403blocked_message拦截响应体内容case_sensitive是否大小写敏感默认false不敏感匹配前统一转小写从源码实现看onHttpRequestHeaders阶段依次做精确 URL 匹配、关键字 URL 匹配、正则 URL 匹配、请求头关键字匹配当配置中存在block_bodies时才读取请求体否则通过ctx.DontReadRequestBody()跳过请求体读取以节省开销onHttpRequestBody阶段再对请求体做关键字匹配并返回阻断响应。五、路由级与域名级生效WasmPlugin 的matchRules字段允许把同一份插件代码以不同的配置应用到指定的 Ingress 或域名上实现路由级、域名级的差异化策略。示例如下apiVersion: extensions.higress.io/v1alpha1 kind: WasmPlugin metadata: name: request-block namespace: higress-system spec: defaultConfig: # 跟上面例子一样这个配置会全局生效但如果被下面规则匹配到则会改为执行命中规则的配置 block_urls: - swagger.html matchRules: # 路由级生效配置 - ingress: - default/foo # default 命名空间下名为 foo 的 ingress 会执行下面这个配置 config: block_bodies: - foo - ingress: - default/bar # default 命名空间下名为 bar 的 ingress 会执行下面这个配置 config: block_bodies: - bar # 域名级生效配置 - domain: - *.example.com # 若请求匹配了上面的域名, 会执行下面这个配置 config: block_bodies: - foo - bar url: oci://your_registry_hub/request-block:2.0.0所有规则会按上面配置的顺序依次执行匹配当有一个规则匹配时就停止匹配并选择匹配的配置执行插件逻辑defaultConfig作为兜底配置只对未被任何matchRules命中的请求生效。这一机制使得单个插件镜像即可同时服务于不同 Ingress 或不同域名的差异化拦截策略无需为每种策略分别构建镜像。六、单元测试在开发 wasm 插件时建议同时编写单元测试来验证插件功能。wasm-go SDK 提供了完整的测试框架github.com/higress-group/wasm-go/pkg/test可以在不启动真实网关的情况下通过模拟测试主机TestHost对插件的配置解析与请求处理逻辑进行验证。单元测试结构示例文档给出的通用测试骨架如下func TestMyPlugin(t *testing.T) { test.RunTest(t, func(t *testing.T) { // 1. 创建测试主机 config : json.RawMessage({key: value}) host, status : test.NewTestHost(config) require.Equal(t, types.OnPluginStartStatusOK, status) defer host.Reset() // 2. 设置请求头 headers : [][2]string{ {:method, GET}, {:path, /test}, {:authority, test.com}, } // 3. 调用插件请求头处理方法 action : host.CallOnHttpRequestHeaders(headers) require.Equal(t, types.ActionPause, action) // 4. 模拟外部调用响应如果需要 // host.CallOnRedisCall(0, test.CreateRedisRespString(OK)) // host.CallOnHttpCall([][2]string{{:status, 200}}, []byte({result: success})) // 5. 完成请求 host.CompleteHttp() // 6. 验证结果如果插件里返回了响应 localResponse : host.GetLocalResponse() require.NotNil(t, localResponse) assert.Equal(t, uint32(200), localResponse.StatusCode) }) }这个示例展示了测试的基本结构创建测试主机 → 注入请求头 → 调用插件处理方法 → 可选模拟外部调用 → 完成请求 → 断言本地响应。测试框架还提供了CallOnHttpRequestBody、GetMatchConfig、GetHttpStreamAction等方法覆盖配置解析、请求头处理、请求体处理、本地响应等全部验证维度。结合 request-block 的完整单测示例参考插件 request-block 自带了一套非常完整的单元测试见 plugins/wasm-go/examples/request-block/main_test.go。其测试配置覆盖了插件的全部规则类型var testConfig func() json.RawMessage { data, _ : json.Marshal(map[string]interface{}{ blocked_code: 403, blocked_message: Access denied, case_sensitive: false, block_urls: []string{blocked, forbidden}, block_exact_urls: []string{/exact-block, /admin}, block_regexp_urls: []string{/api/v\d/blocked}, block_headers: []string{blocked-header, malicious}, block_bodies: []string{blocked-content, spam}, }) return data }()基于该配置测试覆盖了如下典型场景配置解析TestParseConfig通过host.GetMatchConfig()拿到解析后的*RequestBlockConfig逐一断言各规则列表与blockedCode、blockedMessage、caseSensitive的取值URL 关键字拦截TestBlockUrlByKeyword请求/api/blocked/endpoint命中关键字blocked断言返回 403 且响应体为Access deniedURL 精确拦截TestBlockUrlByExactMatch请求/exact-block命中精确规则返回 403URL 正则拦截TestBlockUrlByRegexp请求/api/v1/blocked命中\d正则规则返回 403请求头拦截TestBlockByHeaders携带blocked-header头的请求返回 403请求体拦截TestBlockByBody先调用CallOnHttpRequestHeaders建立上下文再调用CallOnHttpRequestBody注入包含blocked-content的请求体断言返回 403放行合法请求TestAllowValidRequest无命中规则时GetLocalResponse()返回nil请求不被拦截大小写不敏感TestCaseInsensitiveBlockingcase_sensitive: false时大写路径/API/BLOCKED/ENDPOINT同样被拦截自定义拦截状态码TestCustomBlockedCode设置blocked_code: 429时返回 429配置边界情况TestParseConfigEdgeCases验证非法blocked_code如 999回退默认 403、case_sensitive: true时规则保持原大小写、空字符串规则被过滤、完全没有 block 规则时插件启动失败OnPluginStartStatusFailed。运行测试可直接在插件目录执行go test ./...依赖包会通过go.mod拉取wazero 等间接依赖用于在本地模拟 WASM 宿主环境。这一整套测试为插件的正确性提供了充分的回归保障。七、E2E 测试当你完成一个 Go 插件功能时可以同时创建关联的 E2E 测试用例并在本地完成插件功能的端到端验证。E2E 测试会真正把插件加载进 Higress 网关通过真实 HTTP 请求验证拦截行为。step1. 编写 test cases在目录test/e2e/conformance/tests/下面分别添加xxx.yaml文件和xxx.go文件。例如测试插件 request-blocktest/e2e/conformance/tests/request-block.yamlapiVersion: networking.k8s.io/v1 kind: Ingress ... ... spec: defaultConfig: block_urls: - swagger.html url: file:///opt/plugins/wasm-go/examples/request-block/plugin.wasm注意上述url中examples后面的request-block为参考插件所在文件夹名称参考插件不参与官方插件发布。test/e2e/conformance/tests/request-block.go定义suite.ConformanceTest测试结构。仓库中现成的 test/e2e/conformance/tests/go-wasm-request-block.go 是 request-block 的 Go 版 E2E 实现它以foo.com为 Host构造了多组断言访问/swagger.html、/env/info、/web/info期望返回 403POST 请求体为hello world期望返回 403而请求体为hello higress时期望返回 200 放行并校验响应体回显一致性。测试通过http.MakeRequestAndExpectEventuallyConsistentResponse发起请求并等待最终一致的结果。step2. 添加 test cases将上述所写 test cases 添加到 E2E 测试列表中即 test/e2e/e2e_test.go... cSuite.Setup(t) var higressTests []suite.ConformanceTest if *isWasmPluginTest { if strings.Compare(*wasmPluginType, CPP) 0 { m : make(map[string]suite.ConformanceTest) m[request_block] tests.CPPWasmPluginsRequestBlock m[key_auth] tests.CPPWasmPluginsKeyAuth higressTests []suite.ConformanceTest{ m[*wasmPluginName], } } else { higressTests []suite.ConformanceTest{ tests.WasmPluginsRequestBlock, // 这里新增你新写的 case 方法名称 } } } else { ...从代码可以看出测试框架通过命令行参数区分插件语言类型wasmPluginType为CPP时走 C 插件测试分支否则走 Go 插件测试分支并按wasmPluginName选择要执行的测试用例新增的 Go 插件用例只需把自己的ConformanceTest变量加进higressTests列表即可。step3. 编译插件并执行 test cases考虑到本地构建 wasm 比较耗时测试框架支持只构建需要测试的插件同时你也可以临时修改上面第二小步的测试 cases 列表只执行你新写的 casePLUGIN_ROOTexamples PLUGIN_NAMErequest-block make higress-wasmplugin-test该命令会只针对examples/request-block插件进行构建然后执行你在 E2E 列表中登记的相关用例在本地完成从构建、加载到真实请求验证的完整闭环。八、总结围绕 wasm-go SDKHigress 提供了一条完整的 Go WASM 插件开发链路构建既可通过make build/make build-push使用 Higress wasm-go builder 一键完成 wasm 产物与镜像的构建推送也可用GOOSwasip1 GOARCHwasm go build -buildmodec-shared在本地手工编译Go 1.24部署通过extensions.higress.io/v1alpha1的WasmPlugin资源引用 OCI 镜像利用defaultConfig与matchRules实现全局、路由级、域名级的多级差异化配置规则按顺序匹配、命中即止验证单元测试借助pkg/test的 TestHost 模拟宿主环境验证配置解析与拦截逻辑E2E 测试则把插件加载进真实网关后通过 HTTP 断言验证端到端行为。参考插件 plugins/wasm-go/examples/request-block 及其配套的 main_test.go 和 E2E 用例 是理解整个开发流程的最佳起点——你可以把它作为模板替换为自己的业务逻辑快速产出第一个 Higress Go WASM 插件。【免费下载链接】higress AI Gateway | AI Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/hi/higress创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/1 20:38:41

Java抽象类核心特性与应用实践指南

1. Java抽象类概述抽象类是Java面向对象编程中一个非常重要的概念,它介于普通类和接口之间,为代码复用和多态实现提供了强大的支持。抽象类用abstract关键字修饰,它不能被实例化,只能被继承。在实际开发中,抽象类常用于…

2026/11/4 23:08:16

60W反激电源硬件设计包:NCP1377+隔离PCB工程文件

简介:本资源是一份面向电子工程师、硬件开发者及电源设计学习者的完整反激式开关电源工程文件,解决AC220V高压交流电高效、安全转换为DC12V/5A稳定直流输出的实际需求,适用于LED驱动、嵌入式系统供电、小家电电源模块等场景。压缩包共7个文件…

2026/11/11 20:47:06

装修物业要考电工证过期了怎么复审多少钱

装修物业要考电工证过期了怎么复审多少钱 证书过期了不知道怎么复审延期?很多人在装修物业行业工作,尤其是电工岗位,手上拿着低压电工证或高压电工证,却对复审流程一无所知。等到证书快要过期,才发现自己不知道 多少钱…

2026/11/11 20:47:06

基础作业证电工证多少钱?别再被中介坑了,全流程避坑指南

基础作业证电工证多少钱?别再被中介坑了,全流程避坑指南 不知道去哪报名怕被中介坑?特别是基础作业证电工证,很多人被“代办”“包过”“包拿证”这些话术忽悠,结果花了几千块,不仅没拿到证,还耽误了工作。今天就从一个干了10年应急管理行业的老手角…

2026/11/11 20:47:06

高压与低压电工作业实操考试考什么?郑州报考避坑指南全解析

高压与低压电工作业实操考试考什么?郑州报考避坑指南全解析 之前考的证在外省能不能转过来?这个问题是不少打算在郑州从事高压与低压电工作业的朋友最先关心的。其实,国家早就出台政策,支持特种作业操作证的跨省转移,但具体怎么操作,很多新手还是摸不着…

2026/11/11 20:47:06

自贡电工作业报名时间千万别踩坑 这些避坑指南你必须知道

自贡电工作业报名时间千万别踩坑 这些避坑指南你必须知道 你是不是正为找工作四处奔波?手上没有特种作业证,连面试机会都少一半。尤其是自贡地区,电工作业证更是不少企业的硬性要求。但别急, 自贡电工作业报名时间…

2026/11/11 20:47:06

考电工证会有哪些考题官方回应实操考试心里没底怕挂科

考电工证会有哪些考题官方回应实操考试心里没底怕挂科 实操考试心里没底怕挂科,这个问题在特种作业证报考人群中相当普遍。很多刚接触电工证考试的新人,尤其是济源地区初次报考的学员,常常对考试题型、内容、难度一无所知,心里没底,担心挂科。根据…

2026/11/11 20:42:06

利川哪里有考电工证多久拿证 外省证书能转过来吗

利川哪里有考电工证多久拿证 外省证书能转过来吗 之前考的证在外省能不能转过来?这是很多在利川或者打算在利川工作的特种作业人员最关心的问题。如果你之前在别的省市考了电工证,想在当地使用,或者打算在利川重新考一个,那就得了解清楚流程和时间安排,…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/11 0:02:26

考低压电工证通过率考试真题与备考技巧

低压电工证通过率高不高?学历不高也能考,值不值得考? 你是不是总听说电工证能帮你找高薪工作,但又担心自己学历不够,考不上?其实,低压电工证考试门槛并没有你想象中那么高,关键是方法对不对。这篇文章就告诉你, 考低压电工证通过率到底有多高 ,…

2026/11/11 0:02:26

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名 你是不是也和我一样,刚毕业就听说低压电工证学时必须达标才能上岗?可一打听,发现报名机构五花八门,价格参差不齐, 不知道去哪报名怕被中介坑…

2026/11/11 20:27:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑