Easegress Custom Data 全指南:用 CustomDataKind 与 CustomData 实现集群级任意数据持久化
云原生API网关微服务服务网格【免费下载链接】easegressA Cloud Native traffic orchestration system. (CNCF Project)项目地址https://gitcode.com/gh_mirrors/ea/easegress点击查看免费下载导读Easegress 的 Custom Data 特性为集群内的任何数据提供了一套统一、可校验、可订阅的持久化存储供 Pipeline、过滤器等各类组件共享与复用。本文以官方文档为骨架结合仓库源码系统讲解CustomDataKind的类型定义、CustomData的数据约束、完整的 v2 REST API 与egctl操作命令并深入到 etcd 存储布局、JSON Schema 校验与事务批量更新等底层实现帮助你从使用到原理全面掌握这一开发扩展能力。为什么需要 Custom DataEasegress 是一个云原生流量编排系统其内部存在大量组件之外的附属数据需要持久化例如某个过滤器要保存自身的运行状态、某个 Controller 要写入业务自定义的元数据等。这些数据有两种特点Schema 不固定不同组件持久化的数据结构千差万别需要跨成员共享集群中所有节点应当看到同一份数据。为此Easegress 提供了Custom Data特性它实现了一个存储任何数据any data的通用能力可以被其他组件直接用来做数据持久化。由于不同组件的数据结构不同必须通过CustomDataKind自定义数据类型来区分彼此。整个特性由三部分构成CustomDataKind数据类型的定义规定了标识字段与数据校验规则CustomData实际存储的数据项是与 Kind 关联的键值映射API / egctl对外暴露的增删改查与批量操作入口。从源码看存储层实现在 pkg/cluster/customdata/customdata.goAPI 层路由注册在 pkg/api/customdata.go客户端命令则位于 cmd/client 下。CustomDataKind自定义数据类型CustomDataKind用于描述某一类数据的规范它定义了这类数据项的标识字段ID以及可选的 JSON Schema 校验规则。定义示例下面的 YAML 定义了一个名为kind1的 CustomDataKindname: kind1 kind: CustomDataKind idField: name jsonSchema: type: object properties: name: type: string required: - name各字段含义如下字段必填说明name是该 Kind 的名称也是后续数据项的类型名在 API 路径中作为{kind name}使用kind是固定为CustomDataKind标识这是一份类型定义资源idField否数据项中用作唯一标识的字段名默认值为namejsonSchema否一段 JSON Schema 规范若提供则该 Kind 下所有数据项在写入前都会按此规则校验在源码 pkg/cluster/customdata/customdata.go 中Kind结构体的定义与此一一对应type Kind struct { Name string json:name jsonschema:required IDField string json:idField,omitempty JSONSchema dynamicobject.DynamicObject json:jsonSchema,omitempty }idField 的默认与解析逻辑idField的取值逻辑非常直接为空时回退为name。对应源码 GetIDField 与 dataIDfunc (k *Kind) GetIDField() string { if k.IDField { return name } return k.IDField } func (k *Kind) dataID(data Data) string { var id string if k.IDField { id, _ data[name].(string) } else { id, _ data[k.IDField].(string) } return id }即数据项的 ID 就是其idField字段的值同一 Kind 内 ID 必须唯一。测试用例 TestDataID 验证了默认name与自定义key两种场景下的 ID 提取结果。JSON Schema 的两层校验JSON Schema 校验发生在两个时机且都使用gojsonschema库定义 Kind 时PutKind会先加载kind.JSONSchema并调用gojsonschema.NewSchema校验 Schema 本身是否合法非法 Schema 直接拒绝创建customdata.go。写入数据时PutData与BatchUpdateData都会将数据项与 Schema 比对校验失败返回validation failed错误customdata.go。对应的测试 TestPutKind 覆盖了非法 Schema、重复创建、更新不存在 Kind 等失败路径TestPutData 则覆盖了空 ID、校验失败、校验通过等场景。创建 Kind 的命令官方文档给出的两种方式等价egctl create -f kind1.yaml egctl apply -f kind1.yaml两者都支持从文件或 stdin 读取 YAMLcreate对应 HTTPPOSTapply同样通过POST路径落库详见下文批量更新说明。CustomData数据项CustomData本质上是一个 map键必须是字符串值可以是任意合法的 JSON 值嵌套 map 的键同样必须是字符串。在源码中数据项被定义为dynamicobject.DynamicObject即map[string]interface{}customdata.go、dynamicobject.go。dynamicobject.go 中的UnmarshalYAML还特别处理了一个细节从 YAML 反序列化时嵌套 map 可能变成map[interface{}]interface{}标准json包无法处理因此会递归转换为map[string]interface{}——这正是文档要求嵌套 map 的键必须是字符串的根本原因。数据项必须包含 ID 字段每个CustomData数据项必须包含其所属CustomDataKind定义的idField。以上文kind1为例其idField为name因此数据项必须携带name字段作为标识。写入时若 ID 为空PutData会直接报错data id is emptycustomdata.go。数据项示例以下是一个kind1类型的数据项name: data1 field1: 12 field2: abc field3: [1, 2, 3, 4]name: data1是 ID 字段取值为data1field1、field2、field3是任意业务字段值分别为数字、字符串和数组均为合法 JSON 值。数据项的键对应 etcd 存储键同一 Kind 的数据存储在以/custom-data/{kind}/为前缀的键空间下每条数据以idField的值作为键名见下文存储布局。REST API 速查Custom Data 的 REST API 位于 Easegress API Server 的/apis/v2前缀下见 pkg/api/api.go 中的APIPrefixV2常量默认端口2381即http://{ip}:{port}/apis/v2。路由注册在 pkg/api/customdata.go完整端点如下。CustomDataKind 相关 API操作方法URLBody创建 CustomDataKindPOST/apis/v2/customdatakindsKind 定义YAML更新 CustomDataKindPUT/apis/v2/customdatakindsKind 定义YAML查询单个 Kind 定义GET/apis/v2/customdatakinds/{kind name}-列出所有 Kind 定义GET/apis/v2/customdatakinds-删除一个 KindDELETE/apis/v2/customdatakinds/{kind name}-值得注意GET /apis/v2/customdatakinds与GET /apis/v2/customdatakinds/{kind name}返回的每个 Kind 都附带len字段该 Kind 当前的数据条数由DataLen计算得出customdata.go、customdata.go。这也是egctl get customdatakind能打印出 DATA-NUM 列的来源。CustomData 相关 API操作方法URLBody创建 CustomDataPOST/apis/v2/customdata/{kind name}数据项定义YAML更新 CustomDataPUT/apis/v2/customdata/{kind name}数据项定义YAML查询单个数据项GET/apis/v2/customdata/{kind name}/{data id}-列出某 Kind 的所有数据GET/apis/v2/customdata/{kind name}-删除单个数据项DELETE/apis/v2/customdata/{kind name}/{data id}-删除某 Kind 的所有数据DELETE/apis/v2/customdata/{kind name}-批量更新Change RequestPOST/apis/v2/customdata/{kind name}/items变更请求YAML批量删除某 Kind 全部数据DELETE/apis/v2/customdata/{kind name}/items-创建/更新的语义细节从 pkg/api/customdata.go 与 pkg/api/customdata.go 可以看到createPOST走PutData(kind, data, false)数据已存在则报错existedupdatePUT走PutData(kind, data, true)数据不存在则报错not found创建成功后响应头Location会携带新资源的完整路径响应码为201 Created。同理Kind 的创建/更新也遵循这一幂等区分约定PutKind(kind, false)不允许覆盖已存在的 KindPutKind(kind, true)不允许更新不存在的 Kindcustomdata.go。批量更新Change Request对于需要一次性增删多条数据的场景Custom Data 提供了批量更新接口POST /apis/v2/customdata/{kind name}/items请求体是一个 Change RequestYAML结构如下name: kind1 kind: CustomData rebuild: false delete: [data1, data2] list: - name: data3 field1: 12 - name: data4 field1: foo语义说明字段默认值说明name-目标CustomDataKind的名称kind-固定为CustomDatarebuildfalse为true时先删除该 Kind 下的所有既有数据项再处理list中的数据delete-要删除的数据项 ID 数组当rebuild为true时该字段被忽略list-要创建或更新的数据项数组写入采用 upsert 语义同一 ID 直接覆盖底层实现中delete与list的写操作被放进**一个 etcd 事务STM**内原子执行要么全部成功、要么全部失败customdata.go这保证了批量操作的一致性。rebuild的全量清理则由 API 层先调用DeleteAllData完成pkg/api/customdata.go。客户端同样支持以 Change Request 形式创建或应用egctl create -f customdata-change-request.yaml egctl apply -f customdata-change-request.yaml其中name是CustomDataKind名称kind为CustomData。egctl 实战操作egctl 同时保留了新旧两套命令老式命令v1 风格在源码中已标记为(Deprecated)新式命令v2 风格与egctl get/describe/create/apply/delete/edit统一资源模型为推荐用法。新版命令推荐新式命令在 cmd/client/commandv2 中注册资源定义见 cmd/client/resources/customdata.go 与 cmd/client/resources/customdatakind.go# Kind 操作 egctl get customdatakind # 列出所有 Kind egctl get customdatakind kind1 # 查询单个 Kind egctl describe customdatakind kind1 # 描述单个 Kind egctl delete customdatakind kind1 # 删除一个 Kind # 数据操作customdata 支持两级参数kind [id] egctl get customdata kind1 # 列出 kind1 的所有数据 egctl get customdata kind1 data1 # 查询 kind1 下的 data1 egctl describe customdata kind1 data1 egctl delete customdata kind1 data1 # 删除单条数据 egctl delete customdata kind1 --all # 删除 kind1 的全部数据 # 创建 / 应用 / 编辑 egctl create -f kind1.yaml # 创建 Kind或通过 Change Request 写数据 egctl apply -f kind1.yaml egctl edit customdata kind1 # 以批量形式编辑 kind1 的所有数据 egctl edit customdata kind1 data1 # 编辑单条数据几个值得注意的行为均有源码依据get customdata kind默认以表格输出每行仅展示该 Kind 的 ID 字段值describe则打印完整字段customdata.go。edit不允许修改 ID 字段编辑保存时会比较新旧数据的idField值不一致则报错edit cannot change the idField of custom datacustomdata.go。get/describe customdatakind会以表格展示NAME / ID-FIELD / JSON-SCHEMA / DATA-NUM四列customdatakind.go。所有 v2 命令的 URL 均由 cmd/client/general/urls.go 统一定义前缀为/apis/v2。旧版命令已弃用老式命令定义在 cmd/client/command/customdata.goShort描述中明确标注(Deprecated)但功能仍完整可用egctl custom-data-kind list # 列出所有 Kind egctl custom-data-kind get kind # 查询单个 Kind egctl custom-data-kind create -f kind file # 创建 Kind egctl custom-data-kind update -f kind file # 更新 Kind egctl custom-data-kind delete kind # 删除 Kind egctl custom-data list kind # 列出某 Kind 的数据 egctl custom-data get kind id # 查询单条数据 egctl custom-data create kind -f data file # 创建数据 egctl custom-data update kind -f data file # 更新数据 egctl custom-data batch-update kind -f change-request file # 批量更新 egctl custom-data delete kind id # 删除单条数据底层实现存储布局、并发与监听etcd 存储布局Custom Data 最终落在集群的 etcd 中键空间由 pkg/cluster/layout.go 定义customDataKindPrefix /custom-data-kinds/ customDataPrefix /custom-data/Kind 定义存储键/custom-data-kinds/{kind name}数据项存储键/custom-data/{kind name}/{data id}。API Server 初始化时通过Layout()获取这两个前缀并构造 Storepkg/api/server.go后续所有读写都基于cluster.Cluster接口完成GetRaw / Put / Delete / STM 等。并发安全与一致性单条写PutData的已存在/不存在检查基于先读后写批量写则通过cluster.STMetcd 事务包裹确保delete与list原子生效。删除 Kind 的级联行为DeleteKind会先调用DeleteAllData清空该 Kind 下所有数据再删除 Kind 定义本身避免产生悬挂数据customdata.go。DELETE /apis/v2/customdatakinds会一次删除全部 Kind 及其数据DeleteAllKinds属于高危操作。数据变更监听Watch除增删改查外Store 还提供了Watch(ctx, kind, onChange)方法用于持续监听某个 Kind 的数据变更它通过集群 Syncer 拉取该 Kind 前缀下的全部键值每次变化都会以完整数据切片回调onChangecustomdata.go。这为数据变更驱动业务逻辑例如配置下发、规则同步提供了标准机制。实践建议与限制先定义 Kind再写数据PutData会先检查 Kind 是否存在不存在直接返回kind %s not found善用jsonSchema做数据守门它在 Kind 创建与数据写入两个阶段都会校验是保证数据质量的第一道防线大批量更新优先走 Change Request借助 etcd STM 保证原子性避免逐条POST的非事务风险rebuild: true会清空整个 Kind适用于整体替换场景但请确认不会误删存量数据ID 一经写入不可通过edit修改如需变更 ID请走删除 新建流程。说明本文 API 与命令均基于当前仓库源码pkg/api/customdata.go、pkg/cluster/customdata/customdata.go、cmd/client默认 API Server 地址为http://{ip}:2381实际以你的 Easegress 集群配置为准。赞分享云原生API网关微服务服务网格【免费下载链接】easegressA Cloud Native traffic orchestration system. (CNCF Project)项目地址https://gitcode.com/gh_mirrors/ea/easegress点击查看免费下载相关推荐iOS Expanding Collection与Core Data集成数据持久化的终极实践指南iOS Expanding Collection与Core Data集成数据持久化的终极实践指南 Expanding Collection是一个强大的iOS动移动开发UI组件MDS 2.1 快速入门如何在10分钟内理解这个革命性的移动出行数据规范MDS 2.1 快速入门如何在10分钟内理解这个革命性的移动出行数据规范 想要快速掌握全球移动出行数据标准MDS 2.1吗 这篇终极指南将带你了解这个改如何永久保存微信聊天记忆WeChatMsg开源工具终极指南如何永久保存微信聊天记忆WeChatMsg开源工具终极指南 你是否曾担心珍贵的微信聊天记录会随着手机更换而永久消失在数字时代微信对话不仅是简单的文字交流上一篇GrapesJS Trait Manager API 完全指南组件设置面板的配置、事件与自定义类型开发下一篇Envoy HTTP/2 流控整数溢出修复深度解析unconsumed_bytes_ 回绕问题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

ant-design-blazor 倒计时组件(CountDown)实战指南:用法、格式化与底层实现

ant-design-blazor 倒计时组件(CountDown)实战指南:用法、格式化与底层实现

UI组件前端 【免费下载链接】ant-design-blazor 🌈A rich set of enterprise-class UI components based on Ant Design and Blazor. 项目地址: https://gitcode.com/gh_mirrors/an/ant-design-blazor 点击查看 免费下载 导读 本文聚焦 ant-design-bla…

2026/10/12 2:16:16 阅读更多 →
方向·效率·时间:三维价值终极体系全景深度分析/脚踏实地,久久为功

方向·效率·时间:三维价值终极体系全景深度分析/脚踏实地,久久为功

世间所有高阶结果、长期复利、阶层跨越、商业成功、投资盈利,最终只依托三个核心变量:方向、效率、时间。这三者不是并列关系,而是层级递进、因果约束、闭环锁死的终极价值系统。绝大多数人一生平庸、努力无果、进步缓慢、频繁内耗&#xff0…

2026/10/12 2:15:16 阅读更多 →
虚拟器官插件开发教程(20):完整项目——虚拟器官插件平台与全系列收官

虚拟器官插件开发教程(20):完整项目——虚拟器官插件平台与全系列收官

虚拟器官插件开发教程(20):完整项目——虚拟器官插件平台与全系列收官版本声明块 工具/软件:Python 3.11 sqlite3;后端适配目标:SimVascular/svMultiPhysics(BSD-3)、openCARP v19.…

2026/10/12 2:15:16 阅读更多 →

最新新闻

Claude Desktop 正式登陆 Linux:Ubuntu、Debian 开发者终于等到了,TaoToken 统一 Key 接入 Claude Code 实战

Claude Desktop 正式登陆 Linux:Ubuntu、Debian 开发者终于等到了,TaoToken 统一 Key 接入 Claude Code 实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 3:09:47 阅读更多 →
AI修Bug三大安全陷阱与防护指南

AI修Bug三大安全陷阱与防护指南

上周处理一个内部后台的接口报错,我顺手把堆栈信息丢给 AI 让它直接给补丁,30 秒左右它输出了一段修改,测试也全绿。结果第二天就出事了:一个没有管理员权限的普通账号,居然能调通后台的删除类接口。事后看 diff 才发现…

2026/10/12 3:09:47 阅读更多 →
PLC加密不是设密码:实时系统下的三维安全防护体系

PLC加密不是设密码:实时系统下的三维安全防护体系

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 3:09:47 阅读更多 →
操作系统内核实验入门:从零搭建环境到内核启动的踩坑复盘

操作系统内核实验入门:从零搭建环境到内核启动的踩坑复盘

1. 从零上手操作系统内核实验:一个内核小白的踩坑与复盘操作系统这门课,光看书和真正动手写代码之间,隔着一整个太平洋。我当初学操作系统的时候,课本上那些进程调度、虚拟内存、中断处理的概念背得滚瓜烂熟,但真让我说…

2026/10/12 3:09:47 阅读更多 →
Java基础第二阶段:运算符、流程控制、数组与字符串实战指南

Java基础第二阶段:运算符、流程控制、数组与字符串实战指南

很多自学 Java 的朋友,学完变量、数据类型、控制台输入输出之后会突然进入一段迷茫期:语法似乎都眼熟,但真要写个东西出来又不知道该从哪里下手。这个位置恰好就是 java基础-2 要解决的问题。我见过太多人在这里反复翻书、反复看视频&#xf…

2026/10/12 3:09:47 阅读更多 →
手写词法与递归下降分析器:从正则到AST的完整实现

手写词法与递归下降分析器:从正则到AST的完整实现

简介:本资源是华东理工大学2022年《编译原理》课程核心实验的完整交付包,面向计算机专业本科生及编译技术初学者,聚焦词法分析与语法分析两大关键能力训练。压缩包共5个文件(2份Word实验报告、2个C源码文件、1个PL/0测试程序&…

2026/10/12 3:08:47 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →