写点什么

基于 DDD、CQRS、微服务和事件溯源构建系统

  • 2019-11-03
  • 本文字数:1769 字

    阅读完需:约 6 分钟

基于DDD、CQRS、微服务和事件溯源构建系统

对于构建系统来说,模块化是至关重要的,但实现模块化需要应对一些反模块化的做法。两种典型的反模块化做法就是在不考虑业务领域的情况下走捷径和拆分微服务,这会增加技术债务。最近,在由AxonIQ举办的阿姆斯特丹事件驱动微服务大会上,Allard Buijze分享了他的一些想法,以及基于DDDCQRS、微服务和事件溯源构建系统的亲身经验。


Buijze 是 AxonIQ 的 CTO。他指出,另一个反模块化做法就是名词驱动设计(noun-driven design)。名词驱动设计用于发现应用程序中的对象,通常是通过查找应用程序中出现的名词,而非采用那些用于创建服务的对象。如果开发人员需要一次性重新部署多个服务,或是某个服务需要依赖于其他服务,就会从单体应用转为分布式单体应用,但潜在的问题并没有得到解决,这并不是微服务架构。


Buijze 认为,转向微服务需要一个过程,无法一步将业务模型转为微服务。反之,我们应该从那些具有良好结构和模块化的单体应用着手,根据需求逐步拆分出新的微服务。他强调,创建微服务的需求应该是非功能性需求。


Buijze 指出,将组件抽取成微服务的重点在于实现位置透明性。组件不应该知道或者假定知道与之交互的其他组件的位置。这意味着当组件可被抽取为微服务时就无需重写现有组件与新服务之间的通信。


解决位置透明性问题的通常做法是使用事件。一个服务无需直接调用与之通信的其他服务,而是通过发布事件并设置服务去监听事件。Buijze 指出,使用事件的一个重要特点是实现了依赖关系的转置,即订阅事件的组件或服务可以直接监听发送的事件。


Buijze 介绍了只使用事件会出现的一个常见错误,即事件也会被用于间接请求发生于其他服务中的操作,这会增加服务间的耦合度,可能导致双向依赖,使得服务间依赖关系难以编排。如下例,图中没有负责业务流程的服务:



组件间会因为不同的原因发起通信。除了使用事件之外,还存在另外两种消息,一种是用于表示改变事物的“命令”(Command),另一是用于获取信息的“查询”(Query)。在上例中,订单服务(Order)可使用“命令”去请求支付(Payment)和交货(Shipping)服务,交货服务可使用“查询”去请求订单服务细节。Buijze 建议我们应该像使用事件那样同等使用命令和查询。


事件溯源是另一个与事件相关的概念。在使用事件溯源时,组件中存储的并非实体的具体状态,而是导致每个实体状态发生变更的事件。Buijze 认为,事件源就是获取所有的事实,并且只关心事实。但他也指出,事件溯源必须被正确实现,否则就无法确保事实的完整性。要验证事件溯源是否被正确实现,可以试着抛开事件存储以外的东西。如果应用程序的状态可重现,说明事件溯源做对了。Buijze 进一步指出,要在服务中使用事件溯源,服务必须使用自己发布的事件来保持一致的状态。


从业务和技术方面来看,事件溯源都有一些优势,审计和单一数据源就是两个很好的例子。 事件溯源同样存在一些挑战,例如增加了存储规模、实现复杂度高。但 Buijze 认为,这些问题现已不复存在,目前最大的挑战在于事件思维(event thinking)。在 Buijze 看来,事件是一种更为自然的理解应用程序行为的思维方式。他建议,我们应该将注意力放在行为上,而非状态上。事件和命令描述了应用程序的功能,因此让应用程序的行为变得更容易理解。但他并不建议对所有应用程序使用事件溯源。与其他工具一样,事件溯源仅在合适的场景才能发挥作用。


最后,Buijze 强调,所有的通信都是某种形式的合约。基于事件架构的一个缺点是需要对很多未知的组件建立合约。因此,我们要对事件和合约的范围加以约束,避免各个有界上下文之间存在耦合。在同一上下文中,所有服务使用同一种语言,并且能理解所有的事件。但是很多事件,尤其是事件溯源中的事件,只在特定的上下文中是有用的,不应该被发布到上下文之外。对于一些公共事件,一种好的做法是将事件转换为公共 API。


Martin Fowler 在 2015 年发表的一篇博文中提到,他已经注意到乎所有成功的微服务均源于单体应用。但此后不久,Stefan Tilkov 在其博客中提出了不同的看法,即如果目标是实现微服务架构,那么从单体应用着手是完全错误的做法


欧洲2019 DDD大会的一个演讲中,Eric Evans 介绍了各种类型的“有界上下文”,其中一些类型尤其适用于基于事件的系统。


大会演讲全程录像,并将于近几周内公开发布。


原文链接:


Sense and Nonsense in Event Thinking and Microservices


2019-11-03 08:003600

评论

发布
暂无评论
发现更多内容

李飞飞团队 ReKep:空间智能机器人可整合 GPT-4o;苹果首款 AI 手机 iPhone 16 发布丨RTE 开发者日报

声网

深入理解Argo CD工作原理

快乐非自愿限量之名

k8s

AI加持的云端IDE——三种方法高效开发前后端聊天交互功能

豆包MarsCode

人工智能 ide 程序员 AI 编程语言

低代码开发技术在农村现代化中的应用探索

EquatorCoco

低代码 数智化

解锁精准电商营销新纪元:深度剖析京东商品详情API数据驱动的营销策略

代码忍者

api 网关 API 测试

Python存储与读写二进制文件

EquatorCoco

Python

软件测试学习笔记丨Charles 安装及证书配置

测试人

软件测试

什么是 structuredClone?如何实现深拷贝?

伤感汤姆布利柏

云手机能否全面替代传统手机?深入探讨云手机的优缺点

Ogcloud

云手机 海外云手机 云手机海外版 云手机群控 手机群控

软件测试学习笔记丨Postman实战练习

测试人

软件测试

企业智能之旅(4): 智能企业为生成式 AI 做好数据准备

亚马逊云科技 (Amazon Web Services)

代币化资产如何拯救 DeFi:让金融重回价值创造的正轨

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 NFT开发 代币开发

Python将表格文件中某些列的数据整体向上移动一行

不在线第一只蜗牛

Python 机器学习 Excel

软件测试学习笔记丨Vim编辑器的常用命令

测试人

软件测试

数据库运维实操优质文章文档分享(含Oracle、MySQL等) | 2024年8月刊

墨天轮

MySQL 数据库 oracle postgresql 国产数据库

携手浙商证券、华锐技术,共话交易技术的创新与应用

非凸科技

陶建辉演讲干货分享,AI 时代下的数据预测和数据处理挑战

TDengine

tdengine

Acrobat Pro DC 2021 (Win&Mac) 中文特别版

你的猪会飞吗

mac软件下载 Acrobat Pro DC mac mac破解软件下载

说说唯一ID与CAS|得物技术

得物技术

后端 分布式锁 一致性 无锁 企业号2024年8月PK榜

淘宝API大全:淘宝商品详情数据接口

tbapi

淘宝商品详情数据接口 淘宝API接口

中国CRM的出路:先做好该做的

ToB行业头条

企业智能之旅(3): 构建智能企业的文化、组织、人才与能力

亚马逊云科技 (Amazon Web Services)

财务团队应如何推动企业创新升级和可持续发展

智达方通

团队协作 企业管理 战略规划 全面预算管理

Teams电话 中国语音解决方案

cts喜友科技

通信 通讯 云通讯 通信通讯

从 Greenplum 到 Databend,数据仓库的开源新选择

Databend

时隔七年重启编码人生,豆包MarsCode 让我快速回归 | MarsCoders 开发者说

豆包MarsCode

Python 人工智能 程序员 AI

面试官:如何实现线程池任务编排?

不在线第一只蜗牛

面试 线程池

增强洞察力,通过预测性规划引领企业走向光明未来

智达方通

全面预算管理 财务规划和分析 财务管理 财务转型

第67期 | GPTSecurity周报

云起无垠

企业出海网络方案,助力TikTok直播

Ogcloud

海外直播专线 tiktok运营 tiktok直播 tiktok直播专线 tiktok直播网络

DApp开发入门指南:从概念到实践

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 NFT开发 代币开发

基于DDD、CQRS、微服务和事件溯源构建系统_研发效能_Jan Stenberg_InfoQ精选文章