规范路径
先从 canonical path 评估
如果你准备真正使用 Plumego,先从 reference app 和已文档化的默认路径开始,不要把所有可选表面都当成同等成熟。
本版本核心亮点。完整 diff 和 tagged artifact 请见 GitHub Releases。
3 个扩展家族晋升为 beta
x/tenant、x/frontend 和 x/messaging(面向应用的服务层)在两个连续 tagged ref(v1.0.0、v1.1.0)中无导出 API 变化,release-backed 快照已留档,负责人已签字。messaging 下级 primitive 仍为实验性。
x/ai 和 x/data 部分子包确认为 beta 表面
x/ai/provider、x/ai/session、x/ai/streaming、x/ai/tool、x/data/file 和 x/data/idempotency 已有两个 release ref、API 快照和负责人签字。父家族仍为实验性。
Agent 工作流改进
路由、diff 校验、任务打包、recipe 和 manifest 指引扩充,AI 编码助手能更确定地找到落点和验证路径。internal/checks/cross-extension-deps 对实际 Go 导入验证禁止的跨扩展依赖。
网站与双语文档同步
发布姿态、状态、架构、迁移、benchmark 和双语文档页面已同步重建。英文与中文共 77 个文档页面均已就绪。
2026 年 5 月 15 日初始稳定版。完整证据见 docs/release/v1.0.0.md。
9 个稳定根达到 v1 兼容性承诺
core、router、contract、middleware、security、store、health、log、metrics — 公开 API surface 已冻结。破坏性变更需升级主版本号。
4 个扩展家族晋升为 beta
x/gateway、x/observability、x/rest、x/websocket 在两个连续 tagged ref 中无导出 API 变更,已通过 Owner 确认晋级。
路由器在顺序和并发基准中均快于 Chi
Phase 2(池化 RouteState)和 Phase 3(FIFO 缓存、只读 RLock)降低了每次请求的内存分配。顺序:4291 ns/op vs Chi 的 4547 ns/op;并发:663 ns/op vs Chi 的 1013 ns/op。
机器可读控制平面
specs/task-routing.yaml、specs/dependency-rules.yaml 和 specs/change-recipes/ 作为一等制品随版本发布。AI 编程助手和 CI 共享同一套路由与边界模型。
这个页面的目标是把兼容性边界说清楚。你应该能借它分辨:哪些部分可以沿 canonical path 先采用,哪些能力仍在演进,以及哪些发布目标仍然被策略或测试深度明确卡住。
规范路径
如果你准备真正使用 Plumego,先从 reference app 和已文档化的默认路径开始,不要把所有可选表面都当成同等成熟。
矩阵
支持矩阵不是营销文案,它告诉你哪些区域承担更强兼容性预期,哪些仍然需要谨慎。
路线图
一个包可以很有价值、也在积极迭代,但这并不自动意味着它已经拥有和稳定根一样的稳定性承诺。
这些数字直接来自仓库同步事实,不是网站手抄清单。先用它们建立尺度,再进入完整支持矩阵。
稳定根、受支持参考路径、Beta 扩展与实验性扩展家族可以在同一个仓库里,但不能被当成同一种采用风险。
稳定根候选
正在向长期 v1 API 收紧,也是生产服务最适合先评估的范围。
受支持参考路径
与 canonical path 保持对齐。它们是教学和操作表面,不是可任意复用的扩展目录。
Beta — 已晋升扩展
API 在次版本 release ref 之间已冻结。通过两个打标 ref、快照比对和负责人签字后晋升。
实验性 — 扩展家族
纳入发布范围和质量门禁,但 API 兼容性尚未冻结。采用前需要明确理由。
多数读者并不需要一上来就把支持矩阵逐行看完。他们首先需要的是一套默认决策姿态:现在先采用 canonical path,把 supported reference 看成教学表面, 把 experimental capability work 留在明确评估之后再进入。
立即采用
如果你准备把 Plumego 用到真实服务里,先从稳定根、reference app 和已文档化的请求路径开始,再决定是否进入可选表面。
有据可查的评估
七个扩展家族已晋升到 beta——x/rest、x/websocket、x/gateway、x/observability(v1.0.0 晋升)和 x/tenant、x/frontend、x/messaging(v1.1.0 晋升)——导出 API 在两个连续打标 release ref 之间没有变化。采用时应知晓 API 冻结是在 ref 之间而非无条件生效。
审慎评估
面向应用的扩展家族今天已经有实际价值,但只有在你清楚兼容性承诺到哪里结束、产品能力仍会如何演进时,才适合纳入采用范围。
等待更多证据
当你的服务直接依赖下级扩展原语,而不是从所属家族入口进入时,最好等 discovery 路径与兼容性边界更清楚之后再推进采用。
仓库里同时存在多种发布姿态。这个页面的目标,不是把它们抹平成一条乐观叙事,而是帮你分清:哪些表面应该先进入采用决策,哪些能力应该稍后谨慎跟进。
GA 稳定根
这些是由 v1 稳定根承诺覆盖的兼容性承担表面,也是 Plumego 期望多数服务长期依赖的默认能力。
受支持参考路径
这些表面属于官方采用路径,但应该被看成 bootstrap 与操作流的教学工具,而不是一个可以任意平移复用的扩展目录。
Beta
七个家族完成了晋升清单:x/rest、x/websocket、x/gateway、x/observability(v1.0.0),以及 x/tenant、x/frontend、x/messaging(v1.1.0)。两个连续 release ref、导出 API 无变化、release-backed 快照留档、负责人签字。
实验性
这些区域仍处于发布范围和质量门禁之内,但 API 与配置兼容性尚未冻结。采用它们应该有明确理由,而不是默认跟进。
发布姿态由几条简单规则约束:先看默认路径,稳定根保持收敛,可选能力家族允许按不同速度推进。
默认路径
reference/standard-service 和稳定根路径,是判断当前是否可用的主要依据。
边界
扩展家族可以被发布,但不会仅因为存在于仓库里就自动获得与稳定根相同的兼容性承诺。
证据
策略、测试、示例和文档都补齐之后,某个表面才应该被视为真正冻结。
当兼容性比“包好奇心”更重要时,升级最容易的方式,是让发布讨论始终贴着仓库结构走。下面这组步骤可以作为实际升级时的默认顺序。
01
升级前先重新检查你的服务是否仍沿着 canonical bootstrap、routing 与 app-local wiring 路径组织。
02
列出服务真正直接依赖的表面,再把它们映射到 stable、supported-reference 或 experimental 状态。
03
如果服务同时依赖稳定表面与实验性家族,应优先确认稳定根与 canonical path 的变化,再评估扩展区域。
04
用 reference app、request-flow 文档和 architecture 页面,重新确认本地仓库形态是否仍与预期路径保持一致。
下面这张矩阵由仓库事实同步而来,应该被当成采用辅助工具,而不是品牌展示列表。
| 范围 | 状态 | 兼容性承诺 | 模块 |
|---|---|---|---|
| 稳定库根 | GA | 公共包表面承载 v1 稳定根兼容性承诺 | contract, core, router, middleware, security, store, health, log, metrics |
| canonical 参考应用 | 受支持参考路径 | 与 canonical bootstrap 和稳定根用法保持对齐,但不被当作可复用扩展目录 | reference/standard-service |
| CLI | 受支持工具 | 作为命令行工具被支持,不作为 Go 导入表面;命令行为与生成输出必须对齐 canonical docs | cmd/plumego |
| Beta 扩展家族 | Beta | API 表面在次版本 release ref 之间已冻结;需在两个连续打标 ref 无导出 API 变化且负责人签字后才晋升 | x/gateway, x/observability, x/rest, x/websocket, x/tenant, x/frontend, x/messaging |
| 面向应用的扩展家族 | 实验性 | 纳入仓库质量门禁和发布范围,但 API/配置兼容性尚未冻结 | x/fileapi, x/openapi, x/resilience, x/rpc, x/data, x/ai, x/validate |
| 下级扩展原语 | 实验性 | 有维护和测试,但 discovery 应从所属家族入口开始,兼容性尚未冻结 | x/ai/distributed, x/ai/filter, x/ai/instrumentation, x/ai/llmcache, x/ai/marketplace, x/ai/metrics, x/ai/multimodal, x/ai/orchestration, x/ai/prompt, x/ai/provider, x/ai/resilience, x/ai/semanticcache, x/ai/semanticcache/cachemanager, x/ai/semanticcache/embedding, x/ai/semanticcache/vectorstore, x/ai/session, x/ai/sse, x/ai/streaming, x/ai/tokenizer, x/ai/tool, x/data/cache, x/data/file, x/data/idempotency, x/data/kvengine, x/data/migrate, x/data/pgx, x/data/rw, x/data/sharding, x/data/sqlx, x/gateway/cache, x/gateway/discovery, x/gateway/ipc, x/gateway/protocol, x/gateway/protocolmw, x/gateway/transform, x/messaging/mq, x/messaging/pubsub, x/messaging/scheduler, x/messaging/webhook, x/observability/dbinsights, x/observability/devtools, x/observability/featuremetrics, x/observability/ops, x/observability/recordbuffer, x/observability/testlog, x/observability/testmetrics, x/observability/tracer, x/observability/windowmetrics, x/rpc/client, x/rpc/gateway, x/rpc/server |
一个模块不是靠声明变成 beta 的。它必须完成一套有治理的清单:两个连续打标 release ref 且导出 API 无变化、release-backed API 快照留档、负责人签字。 以下四个模块已在 v0.1.0–v0.2.0 完成了这套清单。
两个 release ref
每个晋升模块都用 go run ./internal/checks/extension-release-evidence 在两个 ref 上做了快照。没有任何导出符号发生变化。
快照比对
每个模块的 base 和 head 快照都已提交到 docs/evidence/extension/snapshots/ 并自动比对。仅有 head 快照不足以清除 blocker。
负责人签字
模块负责人在状态字段变更前确认了候选者满足 docs/reference/extension-stability-policy.md 中的 beta 标准。
机器可读台账
specs/extension-beta-evidence.yaml 记录了每个候选模块的 release ref、快照路径、负责人签字状态和未解除的 blocker。
x/rest
负责人:platform-api。证据:路由注册、spec 默认值、repository-backed 控制器、错误语义、分页、离线示例。
x/websocket
负责人:realtime。证据:hub 生命周期、stop 幂等性、容量错误、连接范围迭代、stop 后广播、leave 无操作。
x/gateway
负责人:edge。证据:边缘传输布线、代理配置、路由前缀处理、上游均衡表面。
x/observability
负责人:observability。证据:exporter 和 tracer 布线、collector adapter 表面、可观测性管道集成。
发布标签不是"声明"出来的,而是"跑过"的——一组必须全部通过的门禁检查。下面每一项都是机器执行的,而不是手工勾选的清单。
竞态测试
go test -race -timeout 30s ./... 覆盖整个 module 树。任何包存在竞态或测试失败,发布就无法推进。
边界检查
go run ./internal/checks/dependency-rules 拒绝任何跨越稳定根边界的导入——不管这个改动来自人类还是 AI 编码智能体。
模块清单
go run ./internal/checks/module-manifests 验证每个模块在发布前都有一个与实际包表面匹配的 module.yaml。
参考布局
go run ./internal/checks/reference-layout 确认参考应用遵循文档化的目录结构:main.go、internal/config、internal/app、internal/handler。
格式检查
gofmt -l . 必须返回空列表。未格式化的代码无法进入发布范围,无论由谁编写。
# 一条命令,全部门禁
make gates
# 按顺序运行:
# gofmt -l .
# go run ./internal/checks/dependency-rules
# go run ./internal/checks/module-manifests
# go run ./internal/checks/reference-layout
# go test -race -timeout 30s ./...
Plumego 优化目标是清晰性与正确性,而非原始吞吐量。这组基准测试度量 router.ServeHTTP 的分发成本,
对比对象是 Go 1.22+ http.ServeMux 配合 PathValue() 参数提取——这是 stdlib 中最接近的等价参照。
数值为在同一台机器上五轮三秒运行的中位数。
来源:router/stdlib_bench_test.go,
运行命令:go test -bench=BenchmarkCmp -benchmem -count=5 -benchtime=3s ./router/。
| 场景 | stdlib ns/op | stdlib B/op | plumego ns/op | plumego B/op | 倍数 |
|---|---|---|---|---|---|
| 静态路由(注册 3 条) | 110 | 0 | 367 | 480 | 3.3× |
单 :param + 读取 | 186 | 16 | 807 | 1,104 | 4.3× |
双 :param + 读取 | 332 | 48 | 870 | 1,112 | 2.6× |
四 :param 深路径 | 722 | 112 | 1,036 | 1,184 | 1.4× |
通配符 *filepath + 读取 | 392 | 56 | 813 | 1,112 | 2.1× |
| 70 条路由混合表(50 静态 + 20 参数)循环 | 247 | 8 | 660 | 800 | 2.7× |
| 并发静态(GOMAXPROCS 个 goroutine) | 119 | 0 | 313 | 480 | 2.6× |
| 并发单参数(GOMAXPROCS 个 goroutine) | 128 | 16 | 1,029 | 1,104 | 8.0× |
| 多方法路由(5 种 HTTP method,每个 1 个参数) | 262 | 16 | 1,233 | 1,112 | 4.7× |
开销来源:上下文注入
即使是静态路由,每次请求也会分配约 480 B 和 5 个对象,用于构建 per-request router context。这无法规避:context 需要存储路由元数据、param 槽位以及 response contract 助手,无论参数是否存在。
开销来源:参数映射构建
router 在 trie 遍历时收集参数值,在调用 handler 之前构建 map[string]string。stdlib PathValue 将值懒存储在 request 内部 context 中,直到第一次读取时才分配,避免了 map 提前创建。
开销来源:LRU 缓存争用
每次分发都需要将命中条目提升到 LRU 头部位置。高并发下这需要持有写锁,导致 goroutine 串行化。LRU 缓存使单 goroutine 场景的参数路由吞吐量提升约 20%,但在高并发下引入了争用。如果参数路由处于持续高 QPS,需要评估缓存收益与争用代价之间的取舍。
数字放在上下文里
在 1,000 req/s 下,1 μs 的 router 开销消耗 1 ms/sec CPU——远低于 0.1%。典型 handler 在 I/O 和业务逻辑上花费 1 ms–100 ms;router 占总请求时间的 0.001%–0.1%。成本有界且可预知。这一设计取舍的依据在 为什么选择 Plumego 中有详细说明。
# Go 1.26.0 · linux/amd64 · Intel Xeon @ 2.10 GHz
# 5 轮 · 每轮 3 秒 · 取中位数
go test -bench=BenchmarkCmp -benchmem -count=5 -benchtime=3s ./router/ 成熟度确认完成——下一步是实现。从「开始使用」进入,再参考 reference app 复制目录结构。对于 beta 扩展,导入前请先阅读对应 primer。