基于消息的集成相较于共享数据库的优势难以表述,但我们将在此尝试:
不可避免地会出现争论,DBA希望对实体之间的所有关系进行建模,以便数据始终100%一致。另一方面,开发人员警告DBA关于紧耦合从单片式架构中出现的问题,以及绑定到主表的应用程序无法轻松更改。
我认为这两个论点都只是表面上的,构建一个易于更改的系统具有挑战性,无论您如何进行集成。我想提出SOA和基于消息的集成的另一种论点。
归根结底,问题在于:
- 共享数据库集成通常是由"大系统"视角驱动的。
- 基于消息的集成通常是由"小系统"视角驱动的。
有多少次你遇到过拥有数百用户,支持多种不同业务功能的大型系统?我经常遇到这样的系统。它们似乎是企业软件的主要组成部分。
所有这些系统似乎都有一个共同点,那就是它们改变起来非常昂贵。其中一个原因是,正如Joe R在his answer中所说,紧密耦合。
然而,耦合是一个危言耸听的术语,我认为我们需要考虑两种非常不同的耦合类型。
第一种可以被看作是技术耦合,这意味着技术栈内的垂直耦合,通常在一个层和另一个层之间。
因此,应用程序的数据库和数据访问层之间存在耦合,数据访问层和业务逻辑层之间也存在耦合。普遍认为将这种耦合视为不好或错误的,但理性思考后,我们难道不应该期望或甚至欢迎,例如User DTO、UserRepository类和User数据库表之间高度耦合吗?
让我们考虑一下在实现层面上耦合实际上意味着什么。当多个层基本上相互交谈同一个业务实体时,概念“属于”一个东西泄漏到另一个东西中时就会发生耦合。
第二种类型的耦合是我想要解决的,可以被视为业务能力耦合,也称为水平耦合。这是指属于一个业务能力的概念渗入到另一个业务能力中。
我断言,使用数据库作为集成平台鼓励了这种水平耦合。
举个例子,想象一下支持电子商务网站系统的典型后端系统。通常会有库存、订单、定价和CRM作为核心功能。
如果我们在单个数据库内建模这个领域,实际上就将不同的功能联系在一起。每个外键约束都可能增加这些功能之间的耦合度。事实上,到了这一步,系统已经可以被认为是通过共享数据库集成的几个不同的“服务”。
这是“大系统”世界的图景,通过使用超过500个表的巨型数据库将企业不同领域联系在一起得到支持和鼓励。
相比之下,“小系统”世界的图景与之不同,在我们的示例后端Web应用程序中,库存、订购、定价和CRM是完全独立的应用程序,具有自己的技术堆栈、项目团队、发布计划和数据库。
每个应用程序或“服务”将拥有自己对给定实体的理解,并根据其支持的业务能力来定义该实体。
其中一个例子就是“用户”。 CRM对用户的定义与订购或履行存在非常不同的定义。订购只关心用户正在购买的东西。CRM关心其他方面,如客户购买模式,履行关注姓名、地址等。在共享数据库中使用单个用户表不容易实现这一点。
这张图片对我来说比共享数据库更可取的原因是,生成的系统将更好地模拟它应该支持的实际业务流程。
DDD 的主要原则之一是,系统应尽可能地类似于拥有它的业务。在典型的企业中,这些各种能力不是由跨越大型企业的团队层实现的,而是由小型垂直团队实现的,这些团队通常完全自治,他们相互之间和与其他垂直团队沟通,通常通过发送请求、指令或让其他团队知道某个进程或任务已经开始/完成等方式。
好的,但没有共享数据库,网站现在依赖于来自所有这些不同服务的数据来更新其UI。它仍然需要在同一屏幕上显示这些内容。网站“呈现”层如何组装所有这些并将其呈现给UI?
更重要的是,如果CRM想知道客户何时订购了东西怎么办?如果订单想知道产品价格何时变化,或者库存中的产品缺货怎么办?如果这些服务完全独立,则它们如何交换数据?
首先解决用户界面问题,可以使用
组合用户界面。有许多技术可供选择,但可以说这是一个相对熟知的领域,不是我们关注的重点。
第二个问题是这些服务如何通信,它们通过交换
事件来实现。什么样的事件呢?事件由一个系统发布,以便任何其他对该事件感兴趣的系统消费。
在我们的电子商务示例中,事件的种类可能包括:
- 下单
- 客户升级为金牌会员
- 产品打折
- 库存耗尽
这些事件具有业务含义。这意味着我们可以通过小型系统方法获得额外的好处,即集成媒介本身具有业务含义,并且可以用业务语言表达,这非常适合Scrum和敏捷方法论。
因此,最终回答OP的问题,我认为从技术角度来看,共享数据库与消息集成方法之间没有太大的区别。两种方法都需要相同类型的抽象和语义。但我认为它们背后的驱动力和采用更小系统思维的结果有很大的差异,这提供了更好的整体业务价值。