通过 Higress Wasm 插件 3 倍性能实现 Spring-cloud-gateway 功能
作者:韦鑫,Higress Committer,来自南京航空航天大学分布式系统实验室
导读:本文将和大家一同回顾 Spring Cloud Gateway 是如何满足 HTTP 请求/响应转换需求场景的,并为大家介绍在这种场景下使用 Higress 云原生网关的解决方案,同时还对比了两者的性能差异。
SCG 修改请求/响应
在 Spring Cloud Gateway [ 1] (以下简称为 SCG) 中,当我们需要对 HTTP 请求或响应进行修改时,SCG 提供了许多内置的 GatewayFilter [ 2] 来满足我们对这种应用场景的需求,例如 AddRequestHeader,AddRequestParameter, DedupeResponseHeader,MapRequestHeader, ModifyRequestBody 等。
考虑以下简单用例:
-
添加请求头部 X-First,值从请求路径中获取,例如从 /response-headers?testKey=testValue 中获取 “response-headers”;
-
将请求头部 X-First 的值映射给 X-Second;
-
添加请求查询参数 k1=v1;
-
剔除重复的响应头部 X-Dedupe。
在 SCG 中使用 GatewayFilter 我们可以这样配置:
# application.yaml:spring:cloud:gateway:routes:- id: test_routeuri: lb://httpbin-svcpredicates:- Path=/{api}/**filters:- AddRequestHeader=X-First, {api}- MapRequestHeader=X-First, X-Second- AddRequestParameter=k1, v1- DedupeResponseHeader=X-Dedupe, RETAIN_FIRST
相信拥有 SCG 使用经验的同学对上述配置一定不陌生,那么本文将重点给出另一种能够**满足上述需求并且性能更加优越的解决方案——使用 Higress 云原生网关的 Transformer 插件。
Higress 插件与 SCG 性能比较
我们在同一吞吐量水平(QPS)上,开启/关闭 Higress Transformer 插件 [ 3] 和 SCG 相应 GatewayFilters,统计两者在 CPU 和内存资源上的开销。
经过测试 [ 13] ,我们得到的结论是:
- 在 Higress 未启用 Transformer 插件,SCG 未启用 GatewayFilters 的条件下,SCG 的 CPU, 内存资源开销分别约为 Higress的 3.30, 4.88倍;
- 在 Higress 启用 Transformer 插件,SCG 启用相应 GatewayFilters 的条件下,SCG 的 CPU,内存资源开销分别约为 Higress 的 2.98, 3.19倍。

可见 Higress Transformer 相比于 SCG GatewayFilter 有着相当不错的性能表现!
接下来我们将进一步为大家介绍 Higress 云原生网关以及上述提到的 Higress Transformer 插件。
Higress 简介
Higress [ 4] 是基于阿里内部的 Envoy Gateway 实践沉淀、以开源 Istio + Envoy 为核心构建的下一代云原生网关,实现了流量网关+微服务网关+安全网关三合一的高集成能力,深度集成 Dubbo、Nacos、Sentinel 等微服务技术栈,能够帮助用户极大地降低网关的部署及运维成本且能力不打折;在标准上全面支持 Ingress 与 Gateway API,积极拥抱云原生下的标准 API 规范;同时,Higress Controller 也支持 Nginx Ingress 平滑迁移,帮助用户零成本快速迁移到 Higress。
Higress 提供了一套 Wasm (WebAssembly) SDK [ 5] ,使得开发者能够轻松使用 C++,Golang,Rust 开发 Wasm 插件增强网关能力。下面将为大家介绍 Higress Transformer 插件的基本功能,最后简单说明 Transformer 插件的核心代码逻辑。

Transformer 插件介绍
Higress Transformer 插件可以对请求/响应头部、请求查询参数、请求/响应体参数进行转换,支持的转换操作类型包括删除(remove)、重命名(rename)、更新(replace)、添加(add)、追加(append)、映射(map)和去重(dedupe)。
接下来我们复现最开始提到的 SCG GatewayFilter 简单用例,来演示如何使用该插件(以下使用 Higress 控制台可以很方便地部署插件,当然也可以使用 K8s YAML Manifests 的方式 [ 12] ):
- 首先根据官方文档 [ 6] 快速安装 Higress,结果如下:
$ kubectl -n higress-system get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
higress-console 1/1 1 1 1d
higress-console-grafana 1/1 1 1 1d
higress-console-prometheus 1/1 1 1 1d
higress-controller 1/1 1 1 1d
higress-gateway 1/1 1 1 1d
- 通过 Higress 控制台添加域名(foo.bar.com)、路由配置(foo),将流量转发至后端的 httpbin [ 7] 服务:


- 为 foo 路由添加 Transformer 插件(当前未推送插件至官方镜像仓库,可以先使用 docker.io/weixinx/transformer:v0.1.0,或到代码仓库自行构建):

注:为了能够同时完成请求和响应转换的需求,我们需要为 foo 路由再添加一个 Transformer 插件,命名为 transformer-resp,用于处理响应方向。
- 添加 Transformer 配置并开启该插件:
- 添加请求头部 X-First,值从请求路径中获取,例如从 /response-headers?testKey=testValue 中获取 “response-headers”;
- 将请求头部 X-First 的值映射给 X-Second;
- 添加请求查询参数 k1=v1;
- 剔除重复的响应头部 X-Dedupe。
# transformer:
type: request # 指定 Transformer 类型
rules: # 指定转换规则
- operate: add # 指定转换操作类型headers: # 指定头部转换规则- key: X-Firstvalue: $1 # 正则表达式捕获组 $1,支持 RE2 语法path_pattern: ^\/(\w+)[\?]{0,1}.*$querys: # 指定查询参数转换规则- key: k1value: v1
- operate: mapheaders:- key: X-Firstvalue: X-Second
---
# transformer-resp:
type: response
rules:
- operate: dedupeheaders:- key: X-Dedupevalue: RETAIN_FIRST
- 发送请求进行测试:
# 验证请求方向转换
$ curl -v -H "host: foo.bar.com" "console.higress.io/get"
...
>
< HTTP/1.1 200 OK
...
<
{"args": {# 添加了查询参数 k1=v1"k1": "v1"},"headers": {..."X-First": "get", # 添加了请求头部 X-First,值 "get" 来自请求路径"X-Second": "get" # 映射了请求头部 X-Second},...# 添加了查询参数 k1=v1"url": "http://foo.bar.com/get?k1=v1"
}# 验证响应方向转换
$ 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 的第一个值
...
<
{...# 通过查询参数传给 httpbin 的自定义响应头部"X-Dedupe": ["1","2","3"],...
}
❗️需要注意的是:
- 与上述例子相同,若有同时处理请求和响应转换的需求,则需要为相应路由添加两个 Transformer 插件,分别处理请求方向和响应方向(正在优化);
- 请求体支持的 Content-Type 有:application/json,application/x-www-form-urlencoded,multipart/form-data;而响应体仅支持 application/json;
- 更多说明详见插件文档 [ 3] 。
Transformer 逻辑
本节将简单说明 Higress Transformer 插件的核心代码逻辑,希望可以为有兴趣优化该插件或进行二次开发的同学提供一些帮助。
首先该插件代码位于Higress 仓库的 plugins/wasm-go/extensions/transformer 目录下,使用 Higress 提供的 Wasm SDK [ 5] 进行开发(关于如何开发 Wasm 插件详见官方文档 [ 8] )。
插件的配置模型 TransformerConfig:
# 模型以插件配置的形式暴露给用户
type TransformerConfig struct {typ string # Transformer 类型,[request, response]rules []TransformRule # 转换规则trans Transformer # Transformer 实例,不对用户暴露配置,用于实际的转换操作
}type TransformRule struct {operate string # 转换操作类型headers []Param # header 参数 querys []Param # query 参数body []Param # body 参数
}type Param struct {key string # 表示字段的 keyvalue string # 表示字段的 value 或 key (map) 或 strategy (dedupe)valueType string # 为 application/json body 指定 value 的数据类型hostPattern string # host 正则匹配模式pathPattern string # path 正则匹配模式
}
其中 Transformer 作为接口分别有请求和响应两个实现(requestTransformer, responseTransformer),主要实现了 3 个接口方法 TransformHeaders,TransformerQuerys 和 TransformBody:
type Transformer interface {TransformHeaders(host, path string, hs map[string][]string) errorTransformQuerys(host, path string, qs map[string][]string) errorTransformBody(host, path string, body interface{}) error...
}var _ Transformer = (*requestTransformer)(nil)
var _ Transformer = (*responseTransformer)(nil)
由于头部(Headers)和查询参数(Querys)都是以 key-value 的形式存在,因此通过 kvHandler 对两者采用统一的处理逻辑;而 Body 由于请求、响应支持不同的 Content-Type,因此分别通过 requestBodyHandler (kvHandler,jsonHandler 组合)和 responseBodyHandler (jsonHandler) 进行处理。综上,在修改该插件逻辑时,主要对kvHandler 和 jsonHandler 进行修改即可,其中 jsonHandler 依赖 GJSON [ 9] 和 SJSON [ 10] 工具库。
目前 handler 中的转换顺序是被硬编码的(remove -> rename -> replace -> add -> append -> map -> dedupe),我们对此有优化的打算,也欢迎感兴趣的同学参与进来 ~
总结
本文带大家了解了 Higress Transformer 插件,并与 Spring Cloud Gateway 进行了性能比较,在文章的最后还说明了该插件的核心代码逻辑,希望能够为大家从 Spring Cloud Gateway 迁移至 Higress 提供帮助!
如果您觉得 Higress 对您有帮助,欢迎前往 Github: Higress [ 11] 为我们 star⭐️ 一下!期待与您在 Higress 社区相遇 ~
相关链接:
[1] Spring Cloud Gateway
https://cloud.spring.io/spring-cloud-gateway/reference/html/
[2] SCG GatewayFilter Factories
https://cloud.spring.io/spring-cloud-gateway/reference/html/#gatewayfilter-factories
[3] Higress Transformer 插件
https://github.com/alibaba/higress/tree/main/plugins/wasm-go/extensions/transformer
[4] Higress 官方文档
https://higress.io/zh-cn/
[5] Higress Wasm SDK
https://github.com/alibaba/higress/tree/main/plugins
[6] Higress 快速开始
https://higress.io/zh-cn/docs/user/quickstart
[7] httpbin
https://httpbin.org/
[8] 开发 Higress Wasm 插件
https://higress.io/zh-cn/docs/user/wasm-go
[9] GJSON
https://github.com/tidwall/gjson
[10] SJSON
https://github.com/tidwall/sjson
[11] Higress 代码仓库
https://github.com/alibaba/higress
[12] Transformer Demo
https://github.com/higress-group/higress-demo/tree/main/wasm-demo/wasm-demo-go/wasm-plugin-transformer
[13] 性能对比配置
https://gist.github.com/WeixinX/c24f4ded37832dd7e753b2d27470f0fc
相关文章:
通过 Higress Wasm 插件 3 倍性能实现 Spring-cloud-gateway 功能
作者:韦鑫,Higress Committer,来自南京航空航天大学分布式系统实验室 导读:本文将和大家一同回顾 Spring Cloud Gateway 是如何满足 HTTP 请求/响应转换需求场景的,并为大家介绍在这种场景下使用 Higress 云原生网关的…...
0.618算法和基于Armijo准则的线搜索回退法
0.618代码如下: import math # 定义函数h(t) t^3 - 2t 1 def h(t): return t**3 - 2*t 1 # 0.618算法 def golden_section_search(a, b, epsilon): ratio 0.618 while (b - a) > epsilon: x1 b - ratio * (b - a) x2 a ratio * (b - a) h_…...
DPDK单步跟踪(3)-项目配置和单步跟踪
项目配置 下面都是示例的情况,请大家根据自己的工程来修改 ## 首先是配置CMake build setting Debug setting 这里最重要的是: –proc-type secondary 表示这是以secondary模式启动的dpdk客户端。 ## path mapping 然后根据自己的需要,配置…...
.NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
之前写过使用自定义返回类的方式来统一接口数据返回格式,.Net Core webapi RestFul 统一接口数据返回格式-CSDN博客 但是这存在一个问题,不是所有接口会按照定义的数据格式返回,除非每个接口都返回我们自定义的类,这种实现起来不…...
vue3 使用addRoute动态添加路由,页面刷新就白屏解决办法
问题,通过接口动态添加路由,第一次从登录页跳转还是正常的,说明路由添加成功了,但是刷新后就白屏了,且控制台报错路由匹配不到,在项目的main.js,router和路由拦截器中添加了一大堆打印后发现&am…...
探索鸿蒙:了解华为鸿蒙操作系统的基础课程
目录 学习目标: 学习内容: 学习时间: 学习产出: 介绍鸿蒙操作系统的起源和发展历程。 理解鸿蒙操作系统的核心概念和体系结构。 学习如何搭建和配置鸿蒙开发环境。 掌握基础的鸿蒙应用开发技术,包括应用的创建、…...
【Linux】进程周边007之进程控制
👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.进程创建 2.进程终止 2.…...
【C++】vector容器的模拟实现
目录 一,框架设计 二,构造函数 三,析构函数 四,赋值运算符 五,容器接口的实现 1,迭代器实现 2,“ [] ”运算符的实现 3,swap交换和resize重设大小 4,insert插入…...
华为Harmony——ArkTs语言
文章目录 一、简单示例二、声明式UI描述创建组件无参有参数 配置属性配置事件配置子组件 三、自定义组件基本用法基本结构成员函数/变量 一、简单示例 我们以一个具体的示例来说明ArkTS的基本组成。如下图所示,当开发者点击按钮时,文本内容从“Hello Wo…...
uniapp使用colorUI
colorUI 微动画 | ColorUI 使用文档 1:把colorui里三个文件复制到自己项目中去 App.vue </script> <style> import url(colorui/icon.css); import url(colorui/main.css); import url("colorui/animation.css");-webkit-keyframes show {…...
浅谈测试自动化selenium之POM模式
基于本人也是一个初学者,在运用POM模式的时候记录一下自己的学习笔记。 如果你是大神,那么可以略过,如果你是初学者,希望对你有帮助。 本文阐述了以下几个问题: 什么叫POM模式 为什么要用POM模式 POM模式的思想 POM模…...
什么是事件传播、事件冒泡、事件捕获?
一、事件传播 1、概述 (1)当事件发生在DOM元素上时,该事件并不完全发生在那个元素 (2)在冒泡阶段中,事件冒泡或向上传播至父级、祖父级、祖父的父级,直到 window 为止 (3&#x…...
【uniapp】uniapp中本地存储sqlite数据库保姆级使用教程(附完整代码和注释)
数据库请求接口封装 uniapp中提供了plus.sqlite接口,在这里我们对常用的数据库请求操作进行了二次封装 这里的dbName、dbPath、recordsTable 可以根据你的需求自己命名 module.exports {/** * type {String} 数据库名称*/dbName: salary,/*** 数据库地址* type {…...
微软推出了GPT-RAG:这是一个机器学习库,为在Azure OpenAI上使用RAG模式生产部署大型语言模型(LLMs)提供了企业级参考架构
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
Centos系统升级gcc版本
自己环境的gcc版本太低,影响使用SAN全家桶进行内存泄露检查 当前环境gcc版本查看 gcc --version 进行升级: 1、安装EPEL存储库 yum install epel-release -y 2、确保系统已经更新到最新版本 yum update -y 3、安装GCC编译器及其相关工具包 yum g…...
Http---HTTP响应报文
1. HTTP响应报文分析 HTTP 响应报文效果图: 响应报文说明: --- 响应行/状态行 --- HTTP/1.1 200 OK # HTTP协议版本 状态码 状态描述 --- 响应头 --- Server: Tengine # 服务器名称 Content-Type: text/html; charsetUTF-8 # 内容类型 Transfer-Encoding: chunked # 发送给客…...
iOS 开发设计 App 上架符合要求的截图
1. 真机运行截屏 2. 可以在 Apple developer 官网 Design 下找到 iPhone 边框 https://developer.apple.com/design/resources/ 不用这个边框也行,可以参考已上架 App 的图片框 3. 使用 Procreate(PhotoShop)创建符合要求的画布大小 4. 导入…...
DRF之引入
目录 一、web应用模式 【1】前后端混合开发 【2】前后端分离 二、API接口 三、接口测试工具:Postman 四、RESTful API规范 【1】什么是RESTful 【2】RESTful API的规范 2.1 数据的安全保障 2.2 接口特征表现 2.3 多数据版本共存 2.4 数据即是资源&#…...
【Skynet 入门实战练习】事件模块 | 批处理模块 | GM 指令 | 模糊搜索
文章目录 前言事件模块批处理模块GM 指令模块模糊搜索最后 前言 本节完善了项目,实现了事件、批处理、模糊搜索模块、GM 指令模块。 事件模块 什么是事件模块?事件模块是用来在各系统之间传递事件消息的。 为什么需要事件模块?主要目的是…...
Web组态可视化编辑器-by组态
演示地址: http://www.by-lot.com http://www.byzt.net web组态可视化编辑器:引领未来可视化编辑的新潮流 随着网络的普及和快速发展,web组态可视化编辑器应运而生,为人们在网络世界中创建和编辑内容提供了更加便捷的操作方式。这…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
