如果对各种架构风格都有个透彻的理解,设计者就能够构建新型的、反应性的、有弹性的大型应用。因此,遵循这些经过行业检验的标准可以节省时间、保证可靠性,并推动目标实现。毕竟,企业有什么理由要花时间和资源来重新发明轮子?
但仅仅了解不同的架构,如基于 CRUD 的架构、基于微服务的架构 和基于事件源的架构,并不足以做出全面的决策。我们需要深入了解细节,并理解它们各自的特性、适用性和所提供的价值。在这篇文章中,我们将看一下 CRUD 和事件源架构,思考为什么应该考虑从前者迁移到后者。
CRUD 是创建、读取、更新和删除的缩写。它构成了数据库的四个命令,四个不言自明的命令,这些命令被认为是持久性存储管理的必备要素。这种模式被各行各业的企业广泛用于跟踪客户数据、员工信息、支付记录、账户等。
让我们快速说明一下 CRUD 的常规事件流。Gary 正在浏览一个电子商务网站。他把一个游戏机、一个控制器和一个游戏添加到购物车中。此时,购物车的数据库看起来大概是这样:
假如我们添加另外一个物品(如耳机),则数据库会变成下面这样:
如果 Gary 删除了耳机,则表就会变回之前的样子。此外,如果他另外添加一个控制器,则数据库会变成下面这样:
本质上,数据库遵循创建 - 读取 - 更新 - 删除的方法来维护表。“更新”和 “删除”功能是 CRUD 的特点。
虽然 CRUD 方法由于其操作的轻量化和简单性而备受青睐,但它也有自己的一系列局限,这包括:
对于 CRUD,最常见的批评是原始、过时。与其说它是一种架构或设计,不如说它是一个可供遵循的循环步骤,不管是构建一个数据库还是一个 API。
CRUD 依赖于数据库中状态的持久性。然而,考虑到当前数据操作事件的动态性,这种信息的存储可能是浪费和资源密集型的。
尽管 CRUD 架构很简单,但在开始阶段,它需要人们花费大量的精力编写大量的代码。尽管如此,当涉及到云负载均衡时,CRUD 却无法胜任。
虽然 CRUD 代码开始时可能很简单,但当它开始与其他服务或微服务共享数据时,就会出现与状态同步和故障处理有关的问题。
CRUD 架构所涉及的复杂性将需要同样复杂的解决方案,这可能会延伸到故障跟踪、手动状态记录、异步批处理等。这方面的考虑在编码和整合上都会比较艰难。
在 CRUD 模型中,实体实例通常是双重表示,一是内存中的可变对象,二是关系数据库表中的一个可变行。这样的结构导致了臭名昭著的对象 - 关系阻抗不匹配。试图弥合这种鸿沟的努力却进一步增加了这一架构的复杂性。
事件源是一种数据存储技术,被认为是 CRUD 的升级版。它只关注创建和读取功能,而完全省略了 CRUD 中更新和删除值的操作。更简单地说,你不能通过事件源执行破坏性的操作。
那么,它是如何克服 CRUD 面临的挑战的?
这里有个有趣的地方:与 CRUD 遵循的传统方法不同,事件源将变化逐个记录下来,作为当前状态随时间变化的一系列增量,而不是持久化当前状态本身。通过这种方式,事件源赋予了状态变化可追溯性。在大多数情况下,这种设计通常与领域驱动设计(DDD)和命令查询责任分离(CQRS)设计模式相结合。
为了更好地理解事件源架构,让我们以 Gary 的银行账户为例。假设 Gary 的账户里有 2400 美元。他用 499 美元购买了 PS5 游戏机。电子商务网站为他提供了 49 美元的返现。在这种情况下,事件源表会是这样的:
通过追踪一段时间内的取款和存款,可以计算出他目前的账户余额为 1950 美元。这种状态的复原和事件的回放被称为重放。
我们可以把事件源视为客户活动的日志。
如果我们从电子商务平台的角度来看 Gary 的活动,添加游戏机是第一个事件,添加控制器是第二个事件,以此类推。事实上,结账过程也是一个独立的事件。如果 Gary 不小心在购物车中添加了三个控制器(例如,事件 1、2 和 3),然后他又删除了一个,那么删除也是一个独立的事件:事件 4!
从对事件源的基本理解来看,它似乎是一个更好更完善的替代方案,克服了 CRUD 的缺点。为了进一步说明这一点,让我们看一下事件源已被证明了的优势。
事件源遵循事件驱动的架构,方便在状态变化时可靠地发布事件。
它通过持久化事件而不是领域对象,克服了 CRUD 中出现的对象 - 关系阻抗不匹配问题。
它维护了一系列事件的记录,可以在只限追加的状态下进行操作。通过消除状态跟踪和实体关系的需求,编写读写数据库的事件源代码更容易。
由于保留了实体如何到达当前事件的日志,所以事件源保证了审计数据和交易数据的一致性,因为它们是一样的。此外,它也是一个很好的故障保险,因为数据可以从事件日志中重建。
所有的事件只是被追加到现有的数据库中,并且更新和删除功能已被去掉,事件源架构只关注写入,这提高了其性能。
事件源允许对事件流进行分析,这有助于企业从中获取关键信息。他们可以获得所有系统活动的顶层视图,而不会使写入功能复杂化。
遵循事件源模型的架构更容易测试和调试,因为在引入命令和事件之前,可以对其进行模拟测试。此外,事件日志还可以作为一个很好的调试活动记录,如果发现问题,可以在受控环境中重放事件日志,以了解导致异常的原因。
它可以存储任何类型的信息,任何消费者只要获得授权,就可以访问这些信息。它允许通过时间查询实体在任何时候的状态。因此,它非常灵活。
与单体架构相比,事件源应用程序更容易迁移,因为它们遵循基于微服务的架构。之所以如此,是因为参与事件交换的业务实体之间是松耦合的。
随着越来越多的应用程序需要以有序和异步的方式传递实时数据,企业对事件源的需求也越来越大。此外,它也是在网络规模上消费和管理应用程序日志数据的绝佳方法。在这种情况下,事件源成了一个唯一的事实来源,提高了应用程序的可靠性。
那么,你所在的企业打算何时从 CRUD 迁移到事件源架构?
原文链接:
https://dzone.com/articles/why-do-you-need-to-move-from-crud-to-event-sourcin?accessToken=eyJhbGciOiJIUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhY2Nlc3NfcmVzb3VyY2UiLCJleHAiOjE2NDIxNDU1NzUsImciOiJLOEdoZGtjdlF2SHkzeDhwIiwiaWF0IjoxNjQyMTQ1Mjc1LCJ1c2VySWQiOjI0MzYwNzkwfQ.yHCE5wZnN1J6Gb4eKsvz-XrB82uZpWtFq3OmKmoHzbg
点击底部阅读原文访问 InfoQ 官网,获取更多精彩内容!
周鸿祎不理解“35岁被职场抛弃”;拼多多“砍一刀”绩效打分被评为最低档;阿里宣布9人升任副总裁及以上职位|Q资讯
解读编程语言的2021:Go与Rust走向「成熟」,Kotlin、wasm、Julia「无限生长」
点个在看少个 bug 👇