Wasm
WebAssembly是一种安全执行由其他语言编译的代码的方法。运行时会执行WebAssembly模块(Wasm),这些模块通常是带有.wasm
扩展名的二进制文件。
Wasm HTTP中间件允许您使用编译为Wasm二进制文件的自定义逻辑来处理传入请求或提供响应。换句话说,您可以使用未预编译到daprd
二进制文件中的外部文件来扩展Dapr。Dapr嵌入了wazero以在不使用CGO的情况下实现这一点。
Wasm二进制文件可以从URL加载。例如,使用URL file://rewrite.wasm
可以从进程的当前目录加载rewrite.wasm
文件。在Kubernetes环境中,您可以参考如何:将Pod卷挂载到Dapr sidecar来配置可以包含Wasm模块的文件系统挂载。也可以从远程URL获取Wasm二进制文件。在这种情况下,URL必须精确指向一个Wasm二进制文件。例如:
http://example.com/rewrite.wasm
,或https://example.com/rewrite.wasm
。
组件格式
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: wasm
spec:
type: middleware.http.wasm
version: v1
metadata:
- name: url
value: "file://router.wasm"
- guestConfig
value: {"environment":"production"}
规范元数据字段
用户至少需要指定一个实现http-handler的Wasm二进制文件。如何编译将在后面描述。
字段 | 详情 | 必需 | 示例 |
---|---|---|---|
url | 包含要实例化的Wasm二进制文件的资源URL。支持的方案包括file:// 、http:// 和https:// 。file:// URL的路径相对于Dapr进程,除非它以/ 开头。 |
true | file://hello.wasm ,https://example.com/hello.wasm |
guestConfig | 传递给Wasm来宾的可选配置。用户可以传递由Wasm代码解析的任意字符串。 | false | environment=production ,{"environment":"production"} |
Dapr配置
要应用中间件,必须在configuration中引用它。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: wasm
type: middleware.http.wasm
注意:WebAssembly中间件使用的资源比本地中间件多。这可能导致资源限制比在本地代码中更快达到。生产环境中应控制最大并发。
生成Wasm
此组件允许您使用http-handler应用程序二进制接口(ABI)编译的自定义逻辑来处理传入请求或提供响应。handle_request
函数接收传入请求,并可以根据需要对其进行处理或提供响应。
要编译您的Wasm,您需要使用符合http-handler的来宾SDK(如TinyGo)来编译源代码。
以下是TinyGo中的示例:
package main
import (
"strings"
"github.com/http-wasm/http-wasm-guest-tinygo/handler"
"github.com/http-wasm/http-wasm-guest-tinygo/handler/api"
)
func main() {
handler.HandleRequestFn = handleRequest
}
// handleRequest实现了一个简单的HTTP路由器。
func handleRequest(req api.Request, resp api.Response) (next bool, reqCtx uint32) {
// 如果URI以/host开头,修剪它并分派到下一个处理程序。
if uri := req.GetURI(); strings.HasPrefix(uri, "/host") {
req.SetURI(uri[5:])
next = true // 继续到主机上的下一个处理程序。
return
}
// 提供静态响应
resp.Headers().Set("Content-Type", "text/plain")
resp.Body().WriteString("hello")
return // 跳过下一个处理程序,因为我们已经写了一个响应。
}
如果使用TinyGo,按如下所示编译,并将名为"url"的规范元数据字段设置为输出的位置(例如,file://router.wasm
):
tinygo build -o router.wasm -scheduler=none --no-debug -target=wasi router.go`
Wasm guestConfig
示例
以下是如何使用guestConfig
将配置传递给Wasm的示例。在Wasm代码中,您可以使用来宾SDK中定义的函数handler.Host.GetConfig
来获取配置。在以下示例中,Wasm中间件从组件中定义的JSON配置中解析执行的environment
。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: wasm
spec:
type: middleware.http.wasm
version: v1
metadata:
- name: url
value: "file://router.wasm"
- guestConfig
value: {"environment":"production"}
以下是TinyGo中的示例:
package main
import (
"encoding/json"
"github.com/http-wasm/http-wasm-guest-tinygo/handler"
"github.com/http-wasm/http-wasm-guest-tinygo/handler/api"
)
type Config struct {
Environment string `json:"environment"`
}
func main() {
// 获取配置字节,这是组件中定义的guestConfig的值。
configBytes := handler.Host.GetConfig()
config := Config{}
json.Unmarshal(configBytes, &config)
handler.Host.Log(api.LogLevelInfo, "Config environment: "+config.Environment)
}
相关链接
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.