面向数据的架构DOA - eyassh


这是软件架构中一个鲜为人知的模式,值得更多关注。一个 Joshi 在RTI 的 2007 年白皮书中首次描述了面向数据的架构,2017 年维也纳大学的 Christian Vorhemus 和 Erich Schikuta 在这篇 iiWAS 论文中再次描述了面向数据的架构。DOA 一方面是单体二进制文件和数据存储(单体架构)之间的传统二分法的反转,另一方面是小型、分布式、独立的二进制文件,每个二进制文件都有自己的数据存储(微服务和面向服务的架构)。
在面向数据的架构中,单体数据存储是系统中状态的唯一来源,由松散耦合的无状态微服务执行。
 
在单体服务中,大部分服务器端代码位于一个程序中,该程序与一个或多个数据库通信,处理功能计算的多个方面。
在单体服务器中,代码仍然可以组件化并分离到单独的模块中,但程序的不同组件之间没有强制的API 边界。程序中唯一严格定义的 API 通常是

  • (a)在 UI 和服务器之间(在他们决定的任何 REST/HTTP 协议中)
  • (b)在服务器和数据存储之间(在他们决定的任何查询语言中) ) 或在服务器及其外部依赖项之间。

另一方面,面向服务的体系结构(SOA) 将单体程序分解为每个独立的组件化功能的服务。
由于 SOA 中的每个服务都定义了自己的 API,因此每个服务都可以独立访问并与之交互。开发人员调试或模拟单个部分可以单独调用单个组件,新流程可以重新组合这些单个服务以启用新行为。
微服务是一种面向服务的架构。根据您的要求,它们可能与 SOA 不同,因为这些服务旨在特别小和轻量级,或者它们只是 SOA 的同义词。
随着微服务生态系统的发展,它开始大规模地受到以下问题的影响:
  1. 随着组件数量的增加,集成复杂度的N²增长,
  2. 网络的形状变得难以先验推理;即创建或维护测试环境或沙箱将需要大量推理以确保图中没有任何组件具有外部依赖关系

 
面向数据的架构
在面向数据的架构(DOA) 中,系统仍然围绕小型、松散耦合的组件进行组织,就像在 SOA 微服务中一样。但 DOA 在两个关键方面与微服务不同:
  1. 组件始终是无状态的 :DOA 要求根据集中管理的全局模式来描述数据或状态层,而不是对每个相关组件进行组件化和联合数据存储。
  2. 组件之间的交互被最小化,而是通过数据层进行交互。在我们的交易系统案例中,接收不同证券价格的组件只是在我们的数据存储中以规范的形式发布价格。系统可以通过向数据层查询价格来使用这些价格,而不是通过特定 API 从特定服务(或一组服务)请求价格。在这里,集成成本是线性化的。DOA 模式更改意味着可能需要更新多达N个组件,而不是它们之间的多达N²个连接。

当单个高级数据类型由不同的提供者填充时,这才是真正的亮点。
如果我们用一张表替换一项服务,那么我们并没有简化很多事情。好处是如果有多个相同通用数据类型的源。如果一个交易系统连接到多个市场,每个市场都将客户的请求发布到一个表中,那么下游系统可以查询这个表,而不必担心客户请求来自哪里。
 
既然DOA中组件与组件的交互被最小化了,那么如何用通过数据层的交互来代替今天 SOA 中的组件间通信呢?
  • 1. 数据生产和消费

将组件组织成数据的生产者和消费者是设计 DOA 系统的主要方式。
在 SOA 交易系统中,从市场接受订单的组件可能会生成 RPC 来确定如何对订单进行定价、报价或交易。在 DOA 中,微服务消费接受来自市场的请求(通常以 SOA 方式)并生成RFQ,而微服务生产者则生成定价数据等;另一个微服务会查询 RFQ,连同其所有定价和输出报价、订单或任何自定义需要实现最后的响应数据。
  • 2. 触发动作和行为

组件之间通信的最简单方法虽然是RPC。设计良好的 DOA 系统应该看到其大部分组件间通信被生产者/消费者范式所取代,但您可能仍需要组件 X 直接告诉 Y 执行 Z 的方法。
将 RPC 重构为事件及其影响。即,询问是否不是组件 X 向发生事件E的组件 Y 发送 RPC,而是 X 是否可以生成事件E并让组件 Y 通过使用这些事件来驱动响应?这种方法,我称之为基于数据的事件。
基于数据的事件:是我们通常如何进行组件通信的强大反转。它如此强大的原因是因为它允许我们将松散耦合这个术语提升到一个新的水平。系统不需要知道谁在消费他们的事件,并且生产者不需要担心事件来自哪里,只需担心业务 -这些事件的逻辑语义含义。
 
这种架构不是灵丹妙药。在面向数据的架构消除了各类问题的地方,新的问题出现了:它要求设计人员认真考虑数据所有权。多个写入者修改同一记录的情况可能很脆弱,通常会鼓励系统仔细划分记录写入所有权。而且由于组件间 API 是在数据中编码的,因此必须经过深思熟虑,才能使用一种共享的全局模式。