分布式系统事务随笔

刚作后端大概10个月,从游戏前端开发转向后端,看似熟悉的编程语言,在不一样的领域内实际上要考虑的事情也是全然不一样的。前端

当咱们谈论后端开发,天然而然联想到,后端是服务于前端的,也是承载、服务于业务的一个重要组成部分。系统的稳定性,正确性以及可用性都是须要考虑的问题。数据库

作后端,说简单也简单,说难也很难,简单是由于你只须要对数据进行增删查改,聚合统计就完事了,说难是由于一旦涉及到可用性,必然离不开分布式,然而咱们知道,由分布式而引出的一系列问题才是最为棘手的,更不用说系统安全、部署、监控等一些列的落地措施。编程

你须要确保多个系统的业务数据不混乱,在某些跨服务功能的调用链中保持一致性,当某一个服务调用失败以后进行重试或者回滚。后端

重试须要你的服务具有幂等性,也就是说,当引入重试机制以后,你须要确保一个服务在同一个业务上下文中屡次调用而不会产生额外的影响,例如银行转帐,若是多扣几回钱或者多加了几回钱对于公司的业务以及信誉来讲都是没法接受的,解决这个问题的办法须要引入相似流水号的关联标识,在不一样的服务里面造成一个标识上下文。安全

当咱们的整个后端系统根据业务领域分割为不一样的服务独立成型时,多个服务之间相互调用每每会由于网络缘由而失败。硬件损坏、宕机、天然灾害等一些列不可抗力因素告诉咱们,任何事情都有可能失败,当你的系统规模超过阈值以后,偶然将会转变为必然。咱们要的作的,不该该是想出一个万全之策强力约束保证咱们的系统必定会成功,或者怀着侥幸的心理上线而后惶惶不安的等待系统出现问题。反而更应该思考一下,当系统出现问题以后,如何快速有效的修复失败所带来的影响。由于咱们知道,既然咱们没法保证100%成功,那惟一的出路便想出一个补救措施来预防失败,这每每会更使人更有安全感。网络

在讨论如何解决分布式一致性以前,咱们更应该反过头来看一下,什么是事务,它在单机模式下是如何保证业务的原子性的。咱们每每将业务事务和数据库的事务混为一谈,一般来讲这是没问题的,由于后端作的不就是数据的存储么。但当咱们把这两个进行区分的时候,会发现大多数的时候,咱们所说的事务,仅仅是经过数据库提供的ACID来实现的。当你要对数据库的多个表进行操做的时候,打开一个事务,而且进行相应的更新,而后提交事务,此时要么成功,要么回滚撤销变动,经过数据库提供的ACID保证咱们的数据不会由于受到中断的影响而产生混乱。架构

但若是咱们分布式以后呢?每个业务子系统拥有本身的数据库,你如何保证一个业务流程,在跨子系统调用时保证原子性呢?编程语言

若是咱们把但愿继续寄托于数据库,多个业务子系统使用同一个数据库,数据库自己将会成为瓶颈,这样便失去了一开始设计分布式系统的初衷。分布式

若是某一个子系统失败以后,形成了数据的不一致,此时,要么回滚以前的操做,要么就想办法让这个失败的调用变为成功。设计

A做为业务发起者调用B和C,B成功,C失败,A知道C失败以后该怎么作呢?是从新调用一次C仍是通知B回滚呢?若是通知B回滚的时候也失败了呢?

答案每每是不统一的,每个业务领域都有根据自身状况进行处理的方式。有不少分布式事务协议可以解决些许问题,可是这每每会形成复杂度的提高,致使未来的维护以及拓展变得举步维艰。

CAP定理相信你们都有了解,在任什么时候候咱们要么取CP要么取AP,CP的问题在于复杂、可用性以及可维护性差,AP的问题在于必定的时间内,数据会存在不一致性。若是选择CP,是时候考虑一下业务的分割是否合理,只有极少的状况咱们才须要保证强一致性。

咱们须要一种更为聪明的方法,一种机制来保证咱们的系统可以达成最终一致性,这才是分布式系统须要解决问题的根本之道,而且已经有不少模式方法来帮助咱们达成咱们想要的结果。

换一个角度来说,分布式事务,自己就是一个伪命题,由于系统是脆弱的,有太多太多的因素会形成事情不可控。

咱们要作对的事情,让系统可以根据业务需求变动逐步演进,造成一个良性循环,根据业务需求、目标领域来设计系统,合理的进行分割才是王道。

若是你的系统自己不匹配业务领域,而又把不合理、生搬硬套的架构应用于它,就会出现各类各样的问题,这些问题在某些时候甚至是不可能解决的。

在我看来,有关于解决分布式事务的技术,无非是在为糟糕的设计进行弥补,致使系统到最后臃肿不堪。那么什么是好的设计呢?简单的来讲,它应该符合你所处领域的业务知识,技术是不能解决全部问题的,由于只有当你的业务逻辑说得通,领域模型设计的清晰,巧妙以后,才可以解决那些看似不可能解决的问题。

不要妄想用一套通用的模式去套每个项目需求,这样永远不会摆脱问题。

分布式系统在绝大多数时候,反脆弱、最终一致性才是咱们真正须要去解决的问题。

PS:你的系统究竟有多大才会致使最终一致性会被人为的察觉出来?但咱们知道数据最终将会一致不是吗?:)

相关文章
相关标签/搜索