Netty 通信与会话持久化
This content is not available in your language yet.
先给答案:Seata Netty 请求响应、Future、处理器分发与 GlobalSession/BranchSe…
Section titled “先给答案:Seata Netty 请求响应、Future、处理器分发与 GlobalSession/BranchSe…”Seata Netty 请求响应、Future、处理器分发与 GlobalSession/BranchSession 编码。 正文沿“请求响应图 -> 会话模型 -> 为什么这么设计”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。
主要失效边界集中在“RPC timeout 只说明当前调用没有收到响应,不代表 TC 没有执行请求;事务接口必须允许后续 status/report 查询。、批量发送会增加调度复杂度,message id 与子消息映射不能丢。、session size 限制会把超大的 applicationData/lockKey 变成事务错误,应用侧不应把大对象塞进元数据。”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。
sendSyncRequest -> build RpcMessage(id) -> futures[id] = MessageFuture -> Netty channel.write -> server processMessage -> processor executor -> response(id) -> future.complete -> caller returns连接断开时客户端会清理该 channel 关联的 pending future,避免调用线程无限等待;批量发送则把多个消息合并为 MergeMessage,但同步语义仍需为每个子消息保留映射。
GlobalSession 保存 XID、状态、超时、事务名和分支集合;BranchSession 保存 branch id、branch type、resource id、lock key、client id 和 branch status。二者都实现 SessionStorable,通过 encode/decode 适配持久化层,并在 size check 中限制单条会话过大。
为什么这么设计
Section titled “为什么这么设计”替代方案一: 每次 RPC 使用阻塞连接。问题: 连接创建、线程和故障清理成本高。选择: 长连接 + message id + future 多路复用。
替代方案二: 只在 TC 内存保存 session。问题: TC 重启会丢失未完成事务,无法继续补偿。选择: session 抽象和编码协议把状态交给可替换 store。
替代方案三: 全局 session 内嵌全部分支对象。问题: 分支数量大时读写和序列化膨胀。选择: 支持 lazy load branch,并对序列化大小进行硬限制。
源码坐标索引
Section titled “源码坐标索引”AbstractNettyRemoting#sendSync—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemoting.java:185AbstractNettyRemoting#processMessage—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemoting.java:301AbstractNettyRemotingClient#sendSyncRequest—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingClient.java:161AbstractNettyRemotingClient#sendAsyncRequest—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingClient.java:230AbstractNettyRemotingClient#registerProcessor—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingClient.java:262AbstractNettyRemotingClient#cleanupResourcesForChannel—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingClient.java:454AbstractNettyRemotingServer#sendSyncRequest—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingServer.java:71AbstractNettyRemotingServer#registerProcessor—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingServer.java:119AbstractNettyRemotingServer#processMessage—core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingServer.java:285GlobalSession#encode—server/src/main/java/org/apache/seata/server/session/GlobalSession.java:631GlobalSession#decode—server/src/main/java/org/apache/seata/server/session/GlobalSession.java:774BranchSession#encode—server/src/main/java/org/apache/seata/server/session/BranchSession.java:327BranchSession#decode—server/src/main/java/org/apache/seata/server/session/BranchSession.java:500
- RPC timeout 只说明当前调用没有收到响应,不代表 TC 没有执行请求;事务接口必须允许后续 status/report 查询。
- 批量发送会增加调度复杂度,message id 与子消息映射不能丢。
- session size 限制会把超大的 applicationData/lockKey 变成事务错误,应用侧不应把大对象塞进元数据。
可靠 RPC 的核心是“请求生命周期可观测”:请求 id、future、超时、断连清理和幂等/查询协议必须一起设计。持久化对象则应有稳定编码边界,避免存储实现反向污染业务模型。
面试锚点:Netty 同步请求如何避免串包?连接断开如何处理 pending future?为什么 session 要 encode/decode 和 size check?