在 Apache APISIX 版本(2.11.0)中,咱们新增了对于 WASM 的反对!当初开发者除了能够应用 Lua、Java、Go、Python、JavaScript 等多种编程语言开发 APISIX 的插件之外,也能够用 WASM 来开发插件。
WASM 全称 WebAssembly,与上述具体编程语言运行时的不同之处在于,它是一套字节码规范,专门设计成能够在宿主环境中嵌套应用。
如果某种编程语言提供编译成 WASM 字节码的性能,就能够把该语言的利用编译成 WASM 字节码,运行在某个反对 WASM 的宿主环境中。
听起来,是不是只有某个宿主环境反对 WASM,就能像操作系统一样运行任意利用呢?
但其实这里有个限度,就像操作系统须要实现特定规范的 syscall 一样,要想运行特定的利用,也须要实现该利用所需的 API。
以 JavaScript 为例,尽管同样是 JavaScript 代码,然而针对浏览器写的 JS 模块不能间接用在 npm 包外面,因为两个的 API 不一样。
所以仅仅把 WASM 放到 Apache APISIX 外面并行不通,要想让开发者在 Apache APISIX 上运行 WASM,咱们还须要提供一套专门的 API。
为什么抉择 Proxy WASM
对于如何提供这套 API,咱们已经衡量过两套计划:
- 参考 lua-nginx-module 的接口,实现对应的 WASM 版 API
- 实现 Proxy WASM 这一套规范
Proxy WASM 是 Envoy 的 WASM API 规范。所以上述问题其实等价于,咱们是本人搞一套 API 规范还是复用 Envoy 已有规范呢?
WASM API 规范能够拆成两个方面来看:
- Host,负责提供 API 的实现
- SDK,要想在不同的编程语言外面调用提供的 API,须要应用该语言来实现一套胶水层
如果咱们遵循 Envoy 的规范,劣势在于能够复用 Envoy 现有的 WASM SDK(Proxy WASM SDK),而不足之处在于这套规范是 Envoy 联合本人状况制订的,如果咱们跟着实现,没有本人量身定制那么轻松。
通过社区的探讨后,咱们最终决定采纳 Proxy WASM 规范。「做难且正确的事」,实现 Proxy WASM 天然是难的事,但咱们置信这是正确的事,通过社区的单干和共建,能够构建更加凋敝的生态。
如何在 Apache APISIX 中应用 WASM
Apache APISIX 目前已初步反对 WASM,能够应用 WASM 来编写 fault-injection 插件的局部性能。
上面咱们将联合 proxy-wasm-go-sdk 来讲讲怎么用 WASM 实现注入自定义响应的性能。
步骤一:基于 proxy-wasm-go-sdk 编写代码
实现代码(蕴含 go.mod
和其余)具体细节可参考:https://github.com/apache/api…
这里须要解释下,尽管 proxy-wasm-go-sdk 这个我的项目带了 Go 的名字,但它其实用的是 tinygo 而不是原生的 Go。因为原生的 Go 在反对 WASI(你能够认为它是非浏览器的 WASM 运行时接口)时会有一些问题,详情参考:https://github.com/tetratelab…。
步骤二:构建对应的 WASM 文件
tinygo build -o ./fault-injection/main.go.wasm -scheduler=none -target=wasi ./fault-injection/main.go
步骤三:在 config.yaml
援用该文件
apisix:
...
wasm:
plugins:
- name: wasm_fault_injection
priority: 7997
file: t/wasm/fault-injection/main.go.wasm
通过以上操作,你能够像用 Lua 插件一样用这个 WASM 插件,比方:
---
uri: "/wasm"
plugins:
wasm_fault_injection:
conf: '{"body":"hello world","http_status":200}'
upstream:
type: roundrobin
nodes:
127.0.0.1:1980: 1
留神 WASM 插件的配置都是 conf 字段上面的一条字符串,由对应的插件本人去做解析。
横向测评——条条小道通罗马
Apache APISIX 倒退到当初,曾经有三种编写插件的形式:
- 原生的 Lua way,跑在 APISIX 外面
- 多种语言的内部插件 runner,插件逻辑跑在 APISIX 里面
- 把多种语言编译成 WASM,仍然跑在 APISIX 外面
这三种形式在诸如生态、成熟度等各个方面都差别很大。刚巧咱们都能够用它们来实现 fault-injection,所以能够比比看。
步骤一:配置路由
Lua way 的 fault-injection,天然是应用内置的 fault-injection 插件。Runner way 的 fault-injection 实现具体可参考:https://github.com/apache/api…\_injection.go
让咱们别离给它们配置不同的路由:
---
uri: "/wasm"
plugins:
wasm_fault_injection:
conf: '{"body":"hello world","http_status":200}'
upstream:
type: roundrobin
nodes:
127.0.0.1:1980: 1
---
plugins:
ext-plugin-pre-req:
conf:
- name: fault-injection
value: '{"body":"hello world","http_status":200}'
upstream:
nodes:
127.0.0.1:1980: 1
type: roundrobin
uri: /ext-plugin
---
plugins:
fault-injection:
abort:
body: hello world
http_status: 200
upstream:
nodes:
127.0.0.1:1980: 1
type: roundrobin
uri: /fault-injection
步骤二:理论压测
接下来试着用 wrk 进行压测,具体数据比照如下:
从上述后果能够看到,WASM 版本的性能介于内部插件和原生 Lua 之间。
WASM 版本的性能之所以比内部插件好那么多,是因为 fault-injection 性能简略,所以内部插件 RPC 带来的性能损耗过于显著。思考到咱们还没有对 WASM 实现做任何优化,这种状况曾经让咱们感到称心了。
而 WASM 的另一个益处,就是让咱们一下子领有多语言的反对(这也托了 Proxy WASM SDK 的福)。具体细节可参考下方文档:
-
Rust 版本 fault-injection:
https://gist.github.com/space…
-
AssemblyScript 版本 fault-injection:
https://gist.github.com/space…
路线波折,但前途光明
说了这么多 WASM 的益处,是不是有点心动呢?但它目前并非是一个完满的解决方案,WASM/Proxy WASM 还是有一些不够成熟的中央。比方:
- 编程语言反对待欠缺:原生 Go 的 WASM 反对,次要是基于浏览器环境的,所以咱们不得不用 tinygo 来实现。然而 tinygo 作为一个年老的我的项目,还是有不少局限性。
- Proxy WASM 生态有待成熟: AssemblyScript 版本的 fault injection 实现,并没有 JSON decode 的局部。这是因为 AssemblyScript SDK 是基于 AssemblyScript 0.14.x 版本实现的,而几个开源的 AssemblyScript JSON 库都是针对高版本 AssemblyScript 实现的,没方法用在较为古老的 AssemblyScript 0.14 上。
- WASM 没有内置协程: WASM 目前尚未内置协程,所以没方法很好地被宿主的调度零碎给调度起来。
尽管下面列举了几点不足之处,然而咱们置信这个技术栈的前景是光明的:
- 包含 Apache APISIX 和 Envoy 等开源我的项目对于 WASM 都很看重,有许多初创公司和大企业为 WASM 生态添砖加瓦,这意味着诸如 AssemblyScript SDK 停滞不前这样的艰难,只会是临时。短暂看,Proxy WASM 的生态会枝繁叶茂。
- WASM 作为 serverless 和 edge computing 的宠儿,有着光明的将来。在泛滥理论场景的落地和优化,会更快的解决技术上的有余。
写在最初
Apache APISIX 是个紧跟技术潮流的我的项目,“好风凭借力,送我上青天”,Apache APISIX 反对 WASM 是个长期的过程。
“千里之行,始于足下”,Apache APISIX 为了反对 WASM,曾经发动了 wasm-nginx-module 这个开源我的项目。感兴趣的读者能够关注该项目标停顿,“独行者速,众行者远”,期待你的退出,一起发明世界顶级我的项目。
流动预报
1 月 15 日,Apache APISIX 社区将联结 Apache ShardingSphere 社区为大家带来主题为 「从网关到数据,分布式全链路在线利用实际」 的线上分享。本次流动不仅邀请了来自两大社区的技术大咖,更有 Apache SkyWalking PMC Chair 吴晟作为特邀嘉宾,为大家揭秘由 Apache APISIX、Apache ShardingSphere、Apache SkyWalking 三大社区联手打造的一款反对全链路压测的工具:CyborgFlow。
泛滥精彩议题内容等你来看!
入群交换
扫描下方二维码增加小助手微信,由小助手邀请您进入 Apache APISIX 在线交换群,理解更多社区动静!