[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--zXYq1lhr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/6vnr2s9a9f2uo66kyt96.png)

Envoy 是专为云原生应用程序设计的开源服务代理。它具有多种功能,例如连接池、重试机制、TLS 管理、压缩、健康检查、故障注入、速率限制、授权等。这些功能是通过内置 http 过滤器实现的。今天我将讨论一个特殊的过滤器,它的名称是WASM Filter。

[![由 Emre Savcı 在 excalidraw.com 中绘制<br>

](https://res.cloudinary.com/practicaldev/image/fetch/s--OgUudXR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com /uploads/articles/zrxi0yr80kn319furt2p.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--OgUudXR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/zrxi0yr80kn319furt2p.png)

这篇文章不是为了解释什么是 WASM,所以我将跳过解释 WASM,而是在文章末尾添加相关资源。


为什么我们使用 WASM 过滤器

在 Trendyol 科技。我们使用 Istio 作为服务网格。而我们团队(DevX)的职责是通过开发满足微服务常见需求的应用程序(如缓存、授权、速率限制、跨集群服务发现等)来改善开发人员体验。

既然我们已经在使用 Istio,为什么不利用 Envoy Proxy 的可扩展性优势。

我们的用例是为识别该微服务应用程序的微服务获取 JWT 令牌。当我们想避免每个团队用不同的语言编写相同的代码时,我们可以创建一个 WASM 过滤器并将其注入到 Envoy Proxies 中。

WASM 过滤器的优点:

  • 它允许用任何支持 WASM 的语言编写代码

  • 动态加载代码到 Envoy

  • WASM 代码与 Envoy 隔离,因此 WASM 中的崩溃不会影响 Envoy

在 Envoy Proxy 中有处理传入请求的工作线程。每个工作线程都有自己的 WASM VM。因此,如果您编写基于时间的操作代码,它会为每个线程单独工作。

在 Envoy Proxy 中,每个工作线程都相互隔离,并拥有一个或多个 WASM VM。还有一个概念叫WASM Service用于线程间通信和数据共享(我们不涉及这个)。

[由 Emre Savci在 excalidraw.com 中绘制](https://res.cloudinary.com/practicaldev/image/fetch/s--_xXjIU50--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https: //dev-to-uploads.s3.amazonaws.com/uploads/articles/sb18ug366p0p41nbuy33.png)


在 Go 中编写 WASM

我们将使用tetratelabs/proxy-wasm-go-sdk在 Go 中编写 WASM。我们还需要TinyGo来将我们的 Go 代码构建为 WASM。

我们的用例非常简单,因此我们编写了一个每 15 秒向 JWT Api 发送请求的代码。它提取授权标头并将其值设置为全局变量,并将该值放入每个传入请求的响应标头中。我们还将“hello from wasm”值设置为另一个名为“x-wasm-filter”的标头。

在 OnTick 函数中,我们对 Envoy 称为集群的服务进行 http 调用。

让我们将 go 代码构建为 WASM:

tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go

进入全屏模式 退出全屏模式

现在我们需要配置 Envoy 代理以使用 WASM 过滤器处理传入请求。我们将为我们的 WASM 代码定义一个路由规则和一个 WASM 过滤器,我们还将定义一个代表我们服务的集群。

我把所有的文件放到同一个目录下。现在让我们在 Docker 中运行 Envoy Proxy:

docker run -it — rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0

进入全屏模式 退出全屏模式

正如我们从日志中看到的那样,我们的 WASM 过滤器开始工作并每 15 秒向 JWT Api 发送请求

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--jBcv8Lwl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/6g5d52fe3jt0o42o146p.png)

现在让我们向 Envoy Proxy 发送一个请求。我们将 Envoy 配置为监听来自 1000 端口的传入请求,并使用端口映射启动容器。所以我们可以向 localhost:10000 发送请求:

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--tERCtZsq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/hiffztzdp2qerh2jn8xz.png)

在响应标头中,我们可以看到“x-wasm-filter: hello from wasm”和“x-auth”值。


感谢您到目前为止的阅读。我希望它能让您了解如何以及为什么在 Envoy Proxy 中使用 WASM。

您可以在 github 中查看完整示例:

GitHub 徽标mstrYoda/envoy-proxy-wasm-filter-golang

用 Golang 编写的 Envoy 代理的 WASM 过滤器

特使-代理-wasm-filter-golang

用 Golang 编写的 Envoy 代理的 WASM 过滤器

构建

tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go

使用 WASM 过滤器在 Docker 中运行 Envoy 代理

docker run -it --rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0

在 GitHub 上查看

资源

webassembly.org

WebAssembly | MDN

WebAssembly 是一种可以在现代 Web 浏览器中运行的新型代码——它是一种低级的类汇编语言,具有紧凑的二进制格式,以接近本机的性能运行,并提供 C/C++、C# 和 Rust 等语言带有编译目标,以便它们可以在 Web 上运行。它还被设计为与 JavaScript 一起运行,允许两者一起工作。

图标developer.mozilla.org

Wasm 模块和 Envoy 可扩展性解释,第 1 部分 – 新堆栈

如果您曾经想知道 WebAssembly (Wasm) 是什么以及它如何融入服务网格生态系统,那么这就是您想要阅读的文章。

图标thenewstack.io

GitHub 徽标tetratelabs/proxy-wasm-go-sdk

用于代理的 WebAssembly(Go SDK)

此项目处于早期阶段,API可能会发生变化且不稳定。

WebAssembly for Proxies (Go SDK)Build[许可证](https://github. com/tetratelabs/proxy-wasm-go-sdkLICENSE)

Go SDK forProxy-Wasm,使开发人员可以在 Go 中编写 Proxy-Wasm 插件 此 SDK 由TinyGo提供支持,不支持官方 Go 编译器。

入门

  • 示例目录包含此 SDK 之上的示例代码。

  • OVERVIEW.mdProxy-Wasm 的概述、此 SDK 的 API 以及编写插件时应了解的事项。

要求

  • 去1.17 或更高。

  • TinyGo- 此 SDK 依赖于 TinyGo 并利用其WASI(WebAssembly 系统接口)目标。请按照此处的官方说明安装 TinyGo。

  • Envoy- 要运行已编译的示例,您需要有 Envoy 二进制文件。我们建议使用func -e作为开始使用 Envoy 的最简单方法。或者,您可以按照官方说明进行操作。

安装

go get不能用...

在 GitHub 上查看

[图像描述](https://res.cloudinary.com/practicaldev/image/fetch/s--GTL2o-dm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/vox3yovcym9tyhqn7uvp.png)

你可以关注我:

推特

领英

Github

给我买杯咖啡

Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐