作者:Wei Xin,Higress Committer,南京航空航天大学分布式系统实验室。
导读:本文将和大家一起回顾Spring Cloud Gateway是如何满足HTTP请求响应转换需求场景的,并介绍在这个场景下使用Higress云原生网关的方案,同时对比一下两者的性能差异。
在 Spring Cloud Gateway 中(以下简称 SCG),当我们需要对 HTTP 请求或响应进行更改时,SCG 提供了许多内置的 GatewayFilters满足我们对这个应用场景的需求,比如 AddRequestHeader、AddRequestParameter、DedupeResponseHeader、MapRequestHeader、ModifyRequestBody 等。
请考虑以下简单用例:
添加请求标头 x-first,该值取自请求路径,例如来自 response-headers?testkey=测试值"response-headers";将请求头中 x-first 的值映射到 x-second;添加请求查询参数 k1=v1;重复的响应标头 x-dedupe 将被剔除。 在 SCG 中使用 GatewayFilter,我们可以这样配置它:
# application.yaml:spring: cloud: gateway: routes: -id: test_route uri: lb://httpbin-svc predicates: -path=//** filters: -addrequestheader=x-first, maprequestheader=x-first, x-second - addrequestparameter=k1, v1 - deduperesponseheader=x-dedupe, retain_first
相信有SCG使用经验的同学一定对以上配置很熟悉,所以本文将重点介绍另一种能力一个以卓越的性能满足这些需求的解决方案——使用 Higress 云原生网关的 Transformer 插件。 在相同的吞吐量级别 (QPS) 下,我们打开和关闭 Higress Transformer 插件和 SCG 对应的网关过滤器,用于计算两者的 CPU 和内存资源成本。
测试,我们得出的结论是:
如果 Higress 未开启 transformer 插件,SCG 未开启 GatewayFilters,则 SCG 的 CPU 和内存资源开销约为 330, 4.88次;如果为 Higress 开启了 Transformer 插件,并为 SCG 开启了对应的 GatewayFilters,则 SCG 的 CPU 和内存资源开销约为 298, 3.19次。
可以看出,Higress Transformer 与 SCG GatewayFilter 相比具有相当不错的性能!
接下来,我们将进一步介绍上面提到的 Higress Cloud Native Gateway 和 Higress Transformer 插件。
higress它是基于阿里巴巴内部Envoy Gateway实践沉淀,以开源Istio+Envoy为核心构建的下一代云原生网关,实现了流量网关+微服务网关+安全网关合二为一的高集成能力,深度融合了Dubbo、Nacos、Sentinel等微服务技术栈,可以帮助用户在不妥协的情况下大幅降低网关的部署和运维成本能力在标准上全面支持 Ingress 和 Gateway API,并积极拥抱云原生下的标准 API 规范此外,Higress Controller 还支持 nginx ingress 的平滑迁移,帮助用户零成本快速迁移到 Higress。
Higress 提供了一套 Wasm (WebAssembly) SDK,使开发人员可以轻松使用 C++、Golang 和 Rust 开发 WASM 插件以增强网关能力。 下面将介绍Higress Transformer插件的基本功能,最后简要讲解Transformer插件的核心逻辑。
Higress Transformer 插件支持对请求响应头、请求查询参数和请求响应体参数进行删除、重命名、替换、添加、追加、映射和重复数据删除。
接下来,我们将重现开头提到的 SCG GatewayFilter 的简单用例,演示如何使用插件(以下可以使用 Higress 控制台轻松部署,当然也可以使用 k8s yaml manifests)。
1.首先,根据官方文件快速安装 Higress,结果如下:
$ kubectl -n higress-system get deployname ready up-to-date **ailable agehigress-console 1/1 1 1 1dhigress-console-grafana 1/1 1 1 1dhigress-console-prometheus 1/1 1 1 1dhigress-controller 1/1 1 1 1dhigress-gateway 1/1 1 1 1d
2.通过 higress 控制台添加域名 (foo.)bar.com)、路由配置 (FOO),并将流量发送到后端的 httpbin服务业:
3.在 foo 路由中添加一个 transformer 插件(该插件目前没有推送到官方注册中心,可以先使用 docker。io/weixinx/transformer:v0.1.0,或者去**仓库自己搭建):
注意:为了能够同时完成请求和响应的转换,我们需要为 foo 路由添加另一个 transformer 插件,命名为 transformer-resp,用于处理响应方向。
4.添加转换器配置并启用插件:
添加请求标头 x-first,该值取自请求路径,例如来自 response-headers?testkey=测试值"response-headers";将请求头中 x-first 的值映射到 x-second;添加请求查询参数 k1=v1;重复的响应标头 x-dedupe 将被剔除。
transformer:type: request 指定转换器类型rules: 指定转换规则- operate: add 指定转换操作类型 headers: 指定头部转换规则 - key: x-first value: $1 正则表达式捕获组 $1, 支持 re2 语法 path pattern: ( w+)[querys: 指定查询参数 转换规则 - key.] : k1 value: v1- operate: map headers: -key: x-first value: x-second--- transformer-resp:类型:响应规则:- 操作:重复数据删除标头:-key:x-重复数据删除值:首先保留
5.发送测试请求:
验证请求方向是否转换为 $curl -v -h"host: foo.bar.com" "console.higress.io/get"...http/1.1 200 ok..."headers":,新增查询参数k1=v1"url": ""} 验证响应方向是否$curl -v -h"host: foo.bar.com" \"console.higress.io/response-headers?x-dedupe=1&x-dedupe=2&x-dedupe=3"...http/1.1 200 OK< x-dedupe:1 保留响应标头 x-dedupe 的第一个值。
需要注意的是:
如上例所示,如果需要同时处理请求和响应转换,则需要在对应的路由中添加两个 Transformer 插件,一个用于请求方向,一个用于响应方向(优化中)。请求正文支持以下内容类型:application json、application x-www-form-urlencoded 和 multipart form-data;响应正文仅支持应用程序 json;有关更多信息,请参阅插件文档。本节将简要讲解 Higress Transformer 插件的核心逻辑,希望能为有兴趣优化插件或做二次开发的同学提供一些帮助。
首先,插件** 位于 Higress 仓库的 Plugins Wasm-Go Extensions Transformer 目录下,使用 Higress 提供的 Wasm SDK(有关如何开发 wasm 插件的详细信息,请参阅官方文档。
插件transformerconfig的配置模型:
模型以插件配置的形式向用户公开:type transformerconfig struct、type transformrule struct、type param struct
其中,Transformer 有两种实现方式(requestTransformer 和 responseTransformer 作为接口),主要实现三种接口方法:TransformHeaders、Transformer Queries 和 TransformBody:
type transformer interface ) error ..var _ transformer = (*requesttransformer)(nil)var _ transformer = (*responsetransformer)(nil)
由于标头和查询参数以键值的形式存在,因此 kvhandler 对两者使用统一的处理逻辑由于请求和响应支持不同的内容类型,因此正文分别由 requestbodyHandler(kvhandler、JSONHANDLER 组合)和 responsebodyHandler(JSONHANDLER)处理。 综上所述,在修改插件的逻辑时,可以修改 kvhandler 和 jsonhandler,其中 jsonhandler 依赖于 gjson和 sjson工具库。
目前处理程序中的转换顺序是硬编码的(remove ->rename ->replace ->add ->append ->map ->dedupe),我们计划对此进行优化,欢迎有兴趣的同学参与
本文带大家了解 Higress Transformer 插件,对比一下与 Spring Cloud Gateway 的性能,并在文章末尾讲解插件的核心逻辑,希望能帮助大家从 Spring Cloud Gateway 迁移到 Higress!
如果你觉得 higress 有帮助,请前往 github: higress为我们加星标!期待在 Higress 社区中见到您
相关链接:
1] spring cloud gateway
2] scg gatewayfilter factories
#gatewayfilter-factories
3] Higress Transformer 插件。
4] Higress 官方文档。
5] higress wasm sdk
6] Higress 快速入门。
docs/user/quickstart
7] httpbin
8] 开发 Higress Wasm 插件。
docs/user/wasm-go
9] gjson
10] sjson
11] higress ** 存储库。
12] transformer demo
13] 性能比较配置。