美文网首页
选择一个合适的架构

选择一个合适的架构

作者: water_lang | 来源:发表于2019-05-22 22:56 被阅读0次

从头开始创建一个银行与你通常周日散步的方式完全不同。想象一下,这更像是在一个遥远而未知的丛林中徒步旅行。对于所有困难和长时间的活动,它需要良好的准备和精心挑选工具,以便快速移动,不会半途而废。

在软件中,起决定性的工具不是我们使用的数据库或框架,它甚至不是编程语言,而是架构。简而言之,这就是我们该如何组织代码,使其满足业务领域的技术和运营要求。

我们为核心银行系统定义了至少五个关键要求。

  • Traceability(可追溯性)在审计的情况下,我们必须能够知道该数据是由哪些操作导致的.
  • Performance(性能) 我们的客户看到的银行帐户和业务,但我们的会计师看到的交易在一个非常不同的方式,但两者都应该受益于一个非常快的界面;
  • Availability(可用性) 我们有责任保持和提高人们对支付系统的信心,因为我们不能及时回复授权请求而拒绝银行卡支付将是不可接受的;
  • Consistency(一致性) 每次的交易应该是一个原子性的;
  • Maintainability(可维护性)我们必须能够快速诊断问题并修复它们。你不会乱花别人的钱。此外,我们的代码应该得到全面的测试,整个团队应该能够在不踩到彼此脚趾的情况下工作(在各自的领域下工作)。

可追溯性

我们的业务主要是在于我们的数据。钱本身就只是数据,账户余额是数据库中某个地方的一个数字,它可以让你支付房租、账单和食物。但这还不够,我们希望我们的数据完全透明,能够证明账户上发生的每一项操作都是合理的,从而导致账户当前的余额。我们的架构必须允许通过设计实现这一点。

软件架构中出现了一种名为Event Sourcing(ES)的新模式。这个词最早出现在2005年的Martin Fowler的一篇文章中,但在Greg Young的推动下,2011年开始引起公众兴趣。他2014年的会议讲座是关于这个主题的参考。 ES的口号是系统的状态由导致该状态的所有事件给出。这些事件一旦发出就永远不会被修改,并存储在只会追加的事件存储库(append-only storage 注:就是这个存储库里的东西不会被删除,修改,只能是新增,删除其实就是新增了一个删除事件)中。

图片.png

这种方式非常适合可追溯性,系统中发生的所有事情都在我们的数据库中。但现在即使最简单的查询也变得非常复杂。例如,获得帐户余额会迫使我们在事件存储中把相关的事件进行迭代,比如存款和取款。虽然这看起很简单,它会随着事件的堆积越来越多从而导致查询变得越来越慢。

性能

这就是为什么ES与另一种称为Command Query Responsibility Segregation(CQRS)模式结合使用的原因。此模式使用两个非常不同的实体处理系统中的读取和写入。在这种配置中,ES提供了它们之间非常自然的边界。该架构通常称为CQRS / ES。


CQRS/ES架构

查询端读取来自事件存储的事件,并具有自己的数据库。在收到每个事件之后,它相应地更新自己的数据库。


查询端在收到每个事件之后更新其自己的系统的过程

BankAccount称为事件流的(projection )视图。这种方法在性能和可维护性方面具有极大的优势。

  • 我们可以有任意多的视图。例如,一个用于包含用户、帐户和操作的客户机API。另一种为会计API,包含总分类账、会计变动、资产和负债。这些视图是完全解耦的,因为真相的唯一来源是事件。
  • 我们可以很容易地添加或修复现有的视图。我们所需要做的就是使用新的视图重放所有事件,然后切换到新的数据库。
  • 我们不必在所有的地方都使用SQL,我们可以为每个视图选择不同的存储,具体取决于我们将要进行的查询类型。例如,如果我们需要进行与图形相关的查询,我们可以在Neo4J数据库中使用这些事件。我们还可以将事件传送到ES中去,以进行非常快速的搜索。

这些视图的另一个优点是它们可以独立工作,这使我满足了我们的另一个要求。

可用性

与大多数系统一样,我们的系统需要处理比写入多得多的读操作。然而,我们需要在每个请求上保持较短的响应时间,尤其是在写入方面。如果我们对卡交易授权的响应时间太长,则交易将被拒绝,从而导致我们的客户感到失望。

这就是为什么事件存储必须是异步的原因。这样,写入方可以简单地向其发布事件并继续执行接下的操作,而不是等待所有视图去处理它们。这些事件将投到不同的机器,我们可以吸收大量的查询流量而对写入方面没有任何影响。如果读取方面变得不堪重负,我们甚至可以在多台机器上复制相同的视图,所有机器都连接到事件存储。


该体系结构可以使用异步事件存储和多个投影来处理大查询流量

虽然这对性能非常有益,但现在有一个问题。

写一致性

我们基于给定的命令和系统的当前状态在写入方做出业务决策。如果这个状态在视图端,我们可能会进行脏读,从而根据过时的状态做出决定。

为了解决这个问题,我们将写入部分分成称为聚合的小型有状态组件。其中一个是“银行账户”。聚合处理命令并根据其内部状态生成事件。在以下示例中,这个state就是银行帐户余额。


聚合接收命令并生成事件

聚合使用其状态来做出业务决策。例如,由于资金不足,它可以拒绝撤销命令。


聚合可以拒绝命令

由于每个银行帐户只有一个聚合实例,因此可确保一致性。您还会注意到我们不需要依赖事务和数据库锁。

好消息! Elixir的actor模型非常适合这些聚合。在Elixir中称为GenServer的actor具有状态并在其邮箱中接收消息。它通过设计保证两个消息不能同时处理。它的启动和停止也非常便宜,其中数十万个可以轻松地在一台机器上运行。

可维护性

我们的最终标准是可维护性。 CQRS / ES架构比传统架构更难设置,但它随着时间的推移提高了可维护性。

系统的大多数部分都是纯函数,这意味着它们非常简单易于测试。聚合(我们的大多数业务逻辑都在聚合)接收命令并生成没有副作用的事件。大多数测试都会注入一些命令并简单地检查生成的事件。

由于系统的大多数部分都很小并且彼此分离,因此多个开发人员可以轻松地在不同部分上工作而不会发生冲突。

视图对错误非常宽容,因为我们可以通追溯事件来修复错误。例如,如果我们在会计视图中进行了错误的舍入,我们不需要在修复后迁移数据,我们只需要重放事件。

虽然CQRS / ES并不完美,但我们仔细考虑了所有方面。

缺点

CQRS / ES是一种非常复杂的模式,在处理有些业务上可能比传统系统更复杂。

单一性检查就是一个很好的例子。由于聚合不能相互通信,我们如何检查用户电子邮件是否已被接收?

很清楚地表明CQRS / ES很少适合整个系统,应该谨慎使用。例如,将它用于用户管理和角色没有多大意义,并且这个更适合使用传统的CRUD。

我们如何处理需要写入然后立马来的读请求?例如,注册用户的POST请求应该返回创建的用户,但是立马来的查询命令通过查询视图查不到数据,因为视图是异步更新的。

这些案例很少在实践中发生,如果他们这样做了,则有一些解决方法。

如果事件在事件存储中是不可变的并且必须可重放,那么我们如何处理事件中的重大变化呢?

简短的回答,我们不会做出重大改变。迁移先前的事件是危险的,有点像时间旅行和无可挽回地改变事件的过程。相反,我们为每个事件添加一个版本,并在聚合和投影中处理不同的版本。这意味着我们在设计这些事件时必须非常小心。但是,必须注意的是,例如,处理标准HTTP API的版本控制并不困难。

我们如何处理副作用(注:就是可能会产生新的流程)?例如,我们如何安排未来的作业、向用户发送确认电子邮件或与外部系统交互?

DDD / CQRS还有一个额外的概念叫做“Sage”或“流程管理器”。它会对域事件做出反应并产生新的流程。


Saga处理事件并产生新的流程

总结:

希望您现在对CQRS / ES及其如何满足我们IT基础的需求有一个很好的大体印象。以额外的初始复杂性为代价,我们相信它将帮助我们在正确的方向上扩展并实现我们的目标。基于纯粹的功能,特别是非常适合actor,这种选择与我们选择使用Elixir作为语言和平台是一致的。

如果你碰巧在巴黎(或者很乐意搬迁),有一种疯狂和不可抗拒的冲动,需要学习,编写和发扬CQRS / ES架构中的代码:让我们来谈谈吧!
原文:https://medium.com/margobank/choosing-an-architecture-85750e1e5a03

相关文章

  • 成为一个好的iOS架构师

    架构没有好坏之分,合适的架构就是好的架构。在选择一个合适的架构方式前,要清楚需要做的事情、解决什么问题、业务方面需...

  • 选择一个合适的架构

    从头开始创建一个银行与你通常周日散步的方式完全不同。想象一下,这更像是在一个遥远而未知的丛林中徒步旅行。对于所有困...

  • 从0开始学架构 - 架构设计三原则

    合适原则、简单原则、演化原则,架构设计时遵循这几个原则,有助于做出最好的选择。 合适原则 合适原则宣言:“合适优于...

  • 为Android选择一个合适的架构

    在web开发中存在很多已经非常成熟的框架,比如ROR(Ruby)、Django(Python)、Play(scal...

  • 架构设计

    what 什么是架构? 架构就是分离关注点,各关注点相互隔离又相互配合,围绕一个共同的目的各司其职,评估选择最合适...

  • 亚欧联盟精萃陈春花:高成长企业选择组织架构必须考虑四个因素

    导读:影响高成长企业组织架构选择的因素有很多,怎么才能选择合适的高成长企业组织架构?在本文中,陈春花教授提出四个必...

  • Rails API

    经典 MVC 架构 路由(router)根据请求路径来选择控制器(Controller) 控制器选择合适的视图(V...

  • 【MyBatis】MyBatis修炼之二 Maven项目配置My

    一个好的架构,其实要做的事情是非常简单的,除了深入理解一些架构的原理和组成要素之外,此外就是选择一个合适的技术来解...

  • 1.复杂系统中采用DDD-lite实现模糊需求--架构

    一、概念术语 二、解决方案 选择合适的架构,本文采用的是分层架构,并向六边形架构演进。 1、分层架构 2.六边形架...

  • 软件架构的10个常见模式

    企业规模的软件系统该如何设计呢?在开始写代码之前,我们需要选择一个合适的架构,这个架构将决定软件实施过程中的功能属...

网友评论

      本文标题:选择一个合适的架构

      本文链接:https://www.haomeiwen.com/subject/sdmpzqtx.html