为什么大厂都悄悄放弃了 Seata?
做后端这几年我发现工程师有一个通病看到一个新框架Demo 跑通了文档写得漂亮Star 数够多就觉得找到救星了。然后拍板接入上线。等到生产环境出问题才开始真正读懂那份文档。Seata 就是我交的那笔学费。我用了它 18 个月然后亲手把它删了。说实话我到现在还记得当时接入 Seata 时候的心情。那是 2022 年初我们订单系统刚拆完微服务下单链路横跨订单、库存、积分三个服务。每次开会讨论数据一致性问题我都头大——要么逻辑复杂要么性能差要么代码写出来新人根本看不懂。然后我发现了 Seata。加一个GlobalTransactional注解框架自动搞定分布式事务对业务代码完全透明。我当时的第一反应是这不就是我一直在找的东西吗Demo 跑起来十分钟。那种感觉就像在黑暗里突然摸到了开关。我把文档甩给团队说就用这个了。Seata 是怎么工作的在讲踩坑之前先把原理说清楚不然后面的问题看不懂。Seata 有三个角色TM事务发起方、RM各服务的资源管理器、TC独立部署的事务协调者。Seata 三角色架构图来源seataapacheorg它的 AT 模式是这样运作的每次你执行一条 SQLSeata 会在执行前后各拍一张数据快照存到undo_log表里。如果事务需要回滚就用这张快照把数据还原。Seata AT 模式两阶段提交流程来源seataapacheorg听起来很聪明。但有个细节藏在这套流程里很多人接入的时候没注意——在全局事务提交之前被改动的那行数据会被加上一把全局锁。第一笔债压测的时候还的上线前做全链路压测QPS 跑到 500DBA 打电话过来语气不太好数据库锁等待堆了一大堆问我们在搞什么。拉出监控订单接口 P99 从 80ms 涨到了 640ms。排查了半天才搞清楚热门商品的库存那一行500 个并发请求都在抢同一把全局锁。每个请求还得和 TC 额外通信一次网络来回大概 20ms。P99 不炸才怪。这个细节文档里有写我当时没当回事。后来我跟几个朋友聊发现大家都是这么踩过来的。Demo 没有并发感受不到。压测 QPSP99 延迟DB 锁等待结论10082ms无✅ 正常300160ms偶发⚠️ 有点抖500640ms大量❌ 报警800超时死锁❌ 熔断从一个坑跳进另一个坑我当时的应对方案是换 TCC 模式。TCC 没有全局锁性能确实好很多。代价是你要自己实现三个接口Try、Confirm、Cancel。我让小陈负责改造两周后他提了 PR我去 review看到 Cancel 接口有点懵——里面有一段逻辑我没看懂问他这是干嘛的。他解释了一通我才知道这叫「空回滚」——Try 还没执行Cancel 先到了你得处理这种情况。除此之外还有幂等、悬挂每一个接口都要把这几种异常场景全部考虑进去。我问他每个接口都要这么写他说对。我们有三个服务加起来十七个接口。我默默关掉了 PR 页面坐在那想了一会儿。这不是我想要的方向。我当初选 Seata 就是因为它不侵入业务结果 TCC 把我推回了那个更深的坑里。TC一个藏在架构里的定时炸弹TC 是 Seata 的事务协调者独立部署所有全局事务都要跟它通信。11 月的某个周三下午 3 点线上突然大量报警。和以往不同这次不是慢是所有跨服务的事务全部挂起。原因是 TC 集群有个节点网络抖动持续了 30 秒。就这 30 秒订单接口超时连接池打满用户下单失败。故障持续了将近 4 分钟。复盘的时候我在白板上画了一张图把 TC 圈出来才意识到一件事我在核心链路上引入了一个全局单点它一旦出问题影响面是所有业务。那张让我下定决心的截图DBA 某天下午发来一张图什么话没说。undo_log | 18,432 MB18G。还在涨。AT 模式高并发下全局锁让事务变慢慢事务让undo_log积压清理任务根本追不上写入速度。这张表就悄悄长到了 18G没人注意直到 DBA 发现。凌晨 1 点 47 分钉钉报警群连续弹了十几条消息。P99 2300ms全局锁死锁。三个月内第三次了。我拉着几个人语音盯着那条红线看了大概二十秒。我说摘了吧。没人反对。包括当初力推 Seata 的人也就是我自己。删掉之后我们用的是这个说出来一点都不新鲜本地消息表 MQ 幂等消费。核心思路是这张图Transactional Outbox Pattern在同一个本地事务里写业务数据和消息来源microservicesio下单的时候在同一个本地事务里写订单、同时写一条「待发消息」进 outbox 表。事务提交这两条数据必然同时存在事务回滚两条一起没。原子性天然保证不需要任何框架。然后有个独立进程轮询 outbox 表把消息投到 RocketMQ。下游消费幂等处理失败了 MQ 重试超限进死信队列告警人工处理。就这样。上线一个月订单 P99 从 640ms 降到 68msCPU 峰值砍了一半undo_log那张表连结构都删了。小陈看完方案沉默了三秒说了一句就这对就这。所以 Seata 到底适不适合用我现在回头看觉得当时最大的问题不是选错了工具是想用一个框架把分布式事务这件事完全封装掉。这个想法本身就不现实。强一致性分布式事务本身就很贵没有框架能消灭这个矛盾只能把复杂度转移到某个地方——Seata 把它转移到了全局锁、TC 和 undo_log你最终还是要承担。这些场景用 Seata 是合适的并发量不高峰值 QPS 100业务必须强一致比如金融账务、票务核销团队有人专职维护 TC 集群这些场景建议用消息方案高并发互联网业务QPS 500有热点数据竞争比如秒杀、热门商品库存团队小、迭代快、没人专职维护消息队列加本地消息表没有花哨的概念新来的同学一天就能看懂。这才是我们想要的架构。如果你也踩过类似的坑评论区聊聊。这种事情说出来总比憋着强。