Seata
一、技术选型
选型对象和特性支持 | Seata |
---|---|
模式 | AT、TCC、Saga |
支持数据库类型 | AT支持mysq/oracle/pg tcc/Saga不依赖数据库类型 |
容器化部署 | 支持 |
RPC框架 | dubbo,springboot,gRPC |
TC高可用 | 支持(高可用TCC/saga幂等接口自行控制) |
持久化 | 支持(故障数据) |
重试 | 支持(不断重试,无法保证不重复通知) |
注册中心 | nacos/eureka,redis,zk,consul,sofa |
配置中心 | file,nacos,apollo,zk,consul |
事物的隔离性 | AT支持:脏读@GlobalLock@GlobalTransaction; 脏写:@GlobalTransaction TCC:自行实现 Saga:无法保证隔离性 |
Metrics | 支持 |
二、K8S 部署方案
1、使用集群外zookeeper作为注册中心,使用hostnetwork暴露主机IP和端口注册,使得集群内网均能通过ZK作为服务发现连接Server集群(最终方案)
三、验证内容
1、springcloud微服务集成验证通过
2、Apollo+ZK服务端高可用方案验证通过
3、AT模式支持基于容器的客户端IP漂移故障恢复
4、TCC模式支持基于容器的客户端IP漂移故障恢复
5、K8S高可用部署,验证过程通过F5暴露NG ingress tcp连接,实际上通过注册主机IP供客户端发现连接均验证通过
6、Saga模式故障恢复验证失败,可能存在风险
四、问题及其解决办法
1、Seata处于高速迭代,文档较少,github网站(TCC问题较少)
2、高可用方案二阶段需适用方保证接口的幂等性和可重试,极端情况下可能并发通知(使用方需要二阶段接口实现幂等,可重试,并发通知等)
3、只能通过ZK server高可用方案,F5高可用方案有延时问题不适用OLTP系统(通过ZK注册K8S主机IP可解决)
4、Seata三种模式客户端开启事物耦合度较高,使用上容易混淆(TCC模式稳定暂推)
5、SeaTa客户端于SpringBatch存在冲突(ISSUE确认)
6、TCC强依赖本地事物,否则无法保证二阶段决议提交时某节点挂掉数据恢复(TCC框架均有此问题)
7、AT模式暂不支持联合主键(设计如此)
8、AT模式不支持一个数据库不同用户的多数据源(issue确认设计如此,后续可能优化)
9、AT模式Bug:AT数据类型有相关解析错误;oracle select or update存在问题;AT模式不支持关联SQL更新;(issue确认)
10、saga模式极端情况下故障恢复验证未通过(暂时不推)
五、技术方案
1、Seata TCC问题较少,seata处于持续升级中,其他模式稳定后持续验证和接入,选定Seata作为分布式事物目前的解决方案,主推TCC
六、Seata管控台设计
1、全局事物
xid | transaction_id | status | app_id | transaction_service_group | transaction_name | timeout | begin_time | app_data |
---|---|---|---|---|---|---|---|---|
全局事物id | 事物Id | 状态 | 服务名 | 事物组 | 事物名 | 超时时间 | 开启时间 | 参数 |
2、分支事物
branch_id | xid | transaction_id | resouse_group | resource_id | branch_type | status | client_id | app_data |
---|---|---|---|---|---|---|---|---|
分支事物id | 全局事物id | 事物id | 资源组 | 资源id | 类型 | 状态 | 客户号 | 参数 |
3、TC锁
row_key | xid | transaction_id | branch_id | resource_id | table_name | pk |
---|---|---|---|---|---|---|
唯一标识 | 全局事物id | 事物id | 分支id | 资源id | 表名 | 主键 |
七、k8s istio应用连接seata场景与问题
1、springboot应用注入istio部署k8s,接入seata连接无法成功,报错信息如下:自定义长度解析码器长度校验最大值8388608,实际出现如下超出大小:io.netty,handler.codec.TooLongFrameException:Adjust frame length exceeds:8388608:1345270062
2、解决方案
traffic.sidecar.istio.io/excludeOutboundPorts: “8091”