如果你觉得这篇文章对你有帮助,请不要吝惜你的“关注”、“点赞”、“评价”、“收藏”,你的支持永远是我前进的动力~~~
个人收藏的技术大会分享PDF文档,欢迎点击下载查看!!!
本文是我在做网易考拉海购性能优化时的真实实践,希望对你也有帮助!!!
一、微服务化的困境
微服务是一种架构风格,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。微服务化具有以下优点:
- 灵活性:由于每个服务都可以独立部署和扩展,因此组织可以根据需求快速调整服务的规模和功能,提高了整个应用的灵活性和可维护性。
- 独立性:各个服务之间的解耦程度较高,单个服务的变更不会影响其他服务,降低了项目风险。
- 创新性:微服务鼓励小团队独立开发和迭代,有助于激发团队的创新能力,推动产品的持续改进。
- 可扩展性:服务可以根据负载情况进行水平扩展,轻松应对高流量和大数据场景。
- 容错性:服务之间的隔离性使得个别服务的故障不会导致整个应用的瘫痪,提高了系统的鲁棒性。
但同时,微服务化也存在一些挑战和缺点:
- 复杂性:随着服务数量的增加,管理和服务间的通信会变得更加复杂,需要更多的协调工作和监控机制。
- 数据一致性:在分布式系统中保持数据一致性的难度较大,特别是在处理事务时,需要特别关注数据的最终一致性问题。
- 运维成本:微服务架构下,需要进行更精细的服务治理、部署和监控,这增加了运维的复杂度和成本。
- 系统集成测试:由于服务众多,集成测试的难度和工作量都会大大增加,需要有效的自动化测试策略。
- 技术栈多样性:不同的服务可能会采用不同的技术和框架,这可能导致技术债务和维护困难。
其中最大的挑战我认为是数据的一致致问题。
要彻底服务化、系统要具备水平扩容、独立演进,DB也一定要随业务独立。那边就逃不开数据一致性问题,而通常需要分布式事务来解决。
二、标准TCC
TCC(Try-Confirm-Cancel)是一种分布式事务解决方案,它通过业务层面上的编程来保证事务的最终一致性。下面是TCC技术方案的详细解释:
基本概念
- Try:尝试执行业务操作,完成所有业务检查,预留必须的业务资源。
- Confirm:确认执行业务操作,真正执行业务,不做任何业务检查,只使用Try阶段预留的业务资源。
- Cancel:取消执行业务操作,释放Try阶段预留的业务资源。
实现步骤
- Try阶段:
-
- 完成业务检查,确保业务可以正常执行。
- 预留资源,例如冻结资金、锁定库存等。
- 记录事务日志,用于后续的Confirm或Cancel操作。
- Confirm阶段:
-
- 在Try阶段成功的基础上,执行真正的业务操作。
- 使用Try阶段预留的资源。
- 通常情况下,Confirm阶段不会失败,因为所有业务检查和资源预留都在Try阶段完成了。
- Cancel阶段:
-
- 在Try阶段成功,但Confirm阶段失败或事务需要回滚时执行。
- 释放Try阶段预留的资源。
- 恢复业务数据到Try阶段之前的状态。
关键特性
- 原子性:TCC通过Try、Confirm、Cancel三个操作的原子性来保证整个事务的原子性。
- 一致性:通过Confirm和Cancel的最终执行来保证事务的一致性。
- 隔离性:通过资源预留和释放来避免脏读、脏写等问题。
- 持久性:事务日志的持久化确保了事务的持久性。
实现难点
- 幂等性:Confirm和Cancel操作需要设计成幂等的,以避免重复执行导致的数据不一致。
- 资源预留:如何合理预留资源,以及如何处理资源预留失败的情况。
- 异常处理:如何处理网络异常、系统故障等情况,确保事务能够正确回滚。
适用场景
- 需要强一致性的分布式系统。
- 业务操作可以拆分为Try、Confirm、Cancel三个阶段。
- 系统可以承受资源预留带来的短暂不一致。
三、考拉改进版TCC
我们的目标是构建简单、可靠、高性能的系统
真正重要的是满足业务需求,而不是追求抽象、绝对的系统特性。
我们对分布式事务的需求分析:
- 不强调复用 — 仅下单有强需求
- 下单扣减资源,不会造成资损 – 宁可长款,不可短款
- 事务消息、补偿机制可以解决其他场景
- 不考虑隔离性、嵌套事务等复杂特性
- 成功占绝对数量
因此我们参考标准TCC,结合考拉当时的实际情况,设计了考拉版本的TCC,我们称之为一阶段分布式事务。
考拉下单分布式事务中的TCC(Try-Confirm-Cancel):
- 业务发起方:负责协调整个分布式事务流程的角色,通常称为“事务协调者”。
- 开启事务:这是第一步操作,由业务发起方开始一个新的事务。
- confirm方法 和 cancel方法:
-
- confirm方法:用于确认操作成功的方法。在所有参与方的操作都成功完成后,调用此方法来提交事务。
- cancel方法:用于回滚操作失败的方法。如果在任何一步操作中出现错误或异常情况,则调用此方法来取消之前进行的所有操作。
- 业务参与方A和B:这两个是具体的业务服务节点,它们各自有自己的数据库。
和标准TCC的区别在于,去除了try预留资源的操作,直接扣减资源。因为有扣减之前的资源检查,这一步在绝大多数情况下都是可以成功的,一步就可以完成,这也是我们称之为“一阶段分布式事务”的原因了。
四、考拉版TCC实践
下面是考拉真实的下单分布式事务场景,可以很直观的看出我们的设计流程。这里不作过多解释。
我们的方案具有如下性能优点:
- DB开销非常低
- Dubbo异步开发,减少了耗时和线程开销
- 正向一阶段提交,避免不必要的RPC调用
我们也有阿里集团的公开数据做了对比:
- 集团平均下单RT 462ms
- 考拉平均下单RT 270ms,比集团平均水平要快。
在实现的过程中要注意如下三点:
- 避免xa和减少锁时间:XA是一种分布式事务协议,而减少锁时间意味着减少了事务锁定的时间,这样可以提升系统的并发能力。
- 支持两次空回滚:不能认为当时没有业务数据就无需再次执行回滚操作,要隔一段时间再次执行回滚操作,避免数据落库延迟导致的问题
- 避免回滚风暴