本项目以深 module 为目标:调用方只学习少量稳定 interface,wire format、序列化、关联 ID、连接生命周期和框架接线隐藏在各自实现内部。
核心请求路径固定为:
Protocol Adapter decode
-> Prepared frame / HttpInspection
-> TrafficContext
-> GovernancePipeline.evaluate
-> Forward / LocalReply / Drop
-> protocol-aware data plane
业务 body 默认 opaque。治理元信息在协议 inspect 阶段收集,JSON 元信息只在规则执行 JSONPath 查询时解析。
拥有协议无关的 TrafficContext、调用语义和 Metadata 查询。
- 不依赖具体协议或网络框架。
- 不解析业务 body。
- JSONPath 文档按请求惰性缓存。
拥有 GovernancePipeline、规则编译、匹配、选路和协议无关 Action。
- 调用方只依赖
GovernancePipelineinterface。 - 配置和 JSONPath 在启动期编译。
- 请求热路径不持有全局异步锁。
一次 inspect 同时产生 TrafficContext 与 HttpWireProfile。
- 协议、content-type 和 Triple/gRPC wire flavor 只在这里判断。
- Pingora adapter 不得重新解析 content-type。
- 普通 HTTP/Triple unary 与 H2 RPC 的本地响应及 ALPN 由 profile 决定。
Facade 只拥有 Dubbo envelope、serializer registry 和 prepared frame。
- Hessian2 与 Fastjson2 分别位于独立 serializer module。
- serializer 同时拥有元信息提取与本地错误编码。
- registry 构建后只读,按 5-bit serializer ID O(1) 查找。
- 未知 serializer 保持 opaque;已知但畸形的 payload fail closed。
Facade 组合 TFramedTransport framing 与 Binary/Compact message codec。
- Binary strict/non-strict 和 Compact 的解析、ID 改写、异常编码各自局部。
- 当前只有一种 transport,不提前建立
ThriftTransporttrait。 - 真正增加 THeaderTransport 时,才从两个实现的共同需求提炼 transport seam。
对外只提供 RpcDataPlane、配置和 connector interface。
mod.rs负责编排下游请求、治理 Action 和 facade。connector.rs隔离真实 TCP 与测试字节流。pool.rs隐藏连接池、pending、上下游读写任务、超时和关联 ID 恢复。- 数据面只消费
PreparedRpcFrame,不得重新解析协议 header。
是 Pingora HTTP adapter,不拥有协议分类规则。
proxy.rs负责单次 HTTP exchange 的治理与转发。proxy/bootstrap.rs是 listener 和生产 adapter 的组合根。- Pingora 类型不得进入 traffic、governance 或 TCP protocol module。
RpcFrameAdapter 的 interface 只有三类行为:
decode:增量成帧并一次解析为PreparedRpcFrame;rewrite_correlation_id:使用 prepared frame 缓存的 wire facts 原地改写;encode_local_error:按原请求 wire variant 编码合法拒绝。
PreparedRpcFrame 保证:
- 帧完整且长度已校验;
- direction、correlation ID、response mode 已确定;
- 请求帧携带治理上下文,响应帧不创建无用上下文;
- 改写后缓存事实与 bytes 一致;
into_bytes消费所有权,普通转发没有无条件整帧复制;Thrift Compact sequence ID 的 varint 宽度变化时必须移动其后的 payload,扩宽时还可能触发BytesMut扩容,这是协议编码决定的例外。
HttpInspection 同时包含治理上下文与 wire profile。Proxy 只消费 profile,不复现分类规则。
HTTP 通过 trait object、TCP 通过泛型使用同一个 GovernancePipeline seam;两者不得依赖具体 Pipeline 实现。
| 变化 | 唯一主要修改位置 | 不应修改 |
|---|---|---|
| 新 Dubbo serializer | 新 serializer 文件并注册 DubboSerializer |
TCP 数据面、治理 Pipeline |
| 新 Thrift message protocol | protocol/thrift/<protocol>.rs 和 facade probe |
连接池、治理 Pipeline |
| THeaderTransport | 新 transport module,并在第二个 transport 出现后提炼 seam | Binary/Compact 业务字段解析 |
| 新 HTTP/Triple wire flavor | protocol/http/classify.rs 与 profile 测试 |
Pingora Proxy 治理流程 |
| 新治理实现 | 实现 GovernancePipeline 并在 bootstrap 注入 |
协议 Adapter |
| TLS/自定义连接 | 实现 UpstreamConnector |
RPC framing、关联 ID |
bootstrap/proxy -> data_plane -> protocol
| |
+----------> governance -> traffic
protocol -----------------------> traffic
禁止反向依赖:
- traffic 不依赖 governance、protocol、Pingora;
- governance 不依赖 Pingora 或具体 serializer;
- protocol 不依赖 data_plane 或具体 Pipeline;
- data_plane 不依赖 Dubbo/Thrift 具体类型;
- serializer 不依赖连接池或治理规则。
- 一个完整 RPC envelope 每个方向只解析一次。
- 普通 TCP 转发复用
BytesMut所有权并原地改写 ID;Thrift Compact varint 宽度变化时允许移动 payload 和按需扩容,不承诺该分支为 O(1)。 - pending 必须先登记,再把请求交给上游 writer。
- oneway 不占用 pending 或 in-flight permit。
- 帧、字符串、递归、容器、队列、连接和 pending 都有硬上限。
- 下游半帧读取受超时限制。
- 未知响应 ID 安全丢弃,不能投递给错误请求。
- 新扩展必须通过同一 module interface 的行为测试,不测试私有 cursor 状态。