写点什么

基于 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:003908

评论

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

火山引擎边缘计算节点也支持 MCP 了!快来 get 这份使用教程

火山引擎边缘云

边缘计算 MCP MCP Server

火山引擎携手厂商共同推动手机 AI 应用迈向智能化、全能化新高度

新消费日报

深度解析 Cursor(逐行解析系统提示词、分享高效制定 Cursor Rules 的技巧...)

Baihai IDP

人工智能 AI 智能体 cursor AI 编程

中高考季,盘点AI文档工具有哪些实用的创新?

合合技术团队

人工智能 大数据 算法

Wall-Clock 与 CPU-Cycles 采样的区别

mazhen

Linux Performance perf kernel

强大的3D造型软件犀牛 Rhinoceros 8 for Mac

晨光熹微

华为开发者大会2025来袭,华为云开源邀您一同共赴盛会

华为云开源

开发者 云原生 华为云开源 华为开发者大会2025

Auto Mouse Click for Mac|解放双手!鼠标连点/挂机一键搞定

柠檬与橘子

微擎生态驱动的全场景社交商业赋能

微擎应用市场

PDF阅读器管理您的PDF文件PDF Reader Pro for mac

晨光熹微

高级文件搜索应用工具ProFind for Mac

晨光熹微

Raw查看器FastRawViewer for mac

晨光熹微

B2B企业如何快速实现SCRM搭建?Custouch市场易来助力!

极客天地

MountMate for Mac|外接硬盘管家,一键搞定挂载/卸载!

柠檬与橘子

FastRawViewer for Mac|RAW 文件秒开神器,摄影师必备!

柠檬与橘子

100%加密计算+端云延迟无感:火山引擎如何实现AI安全与性能兼得?

新消费日报

SSH终端应用Prompt 3 for mac

晨光熹微

CST热仿真CHT求解器--水冷

思茂信息

仿真 cht CST Studio Suite 散热

九家Top手机厂商牵手火山引擎,共建AI助手新生态

新消费日报

大模型技术持续演进,安卓厂商携手火山引擎加速推动AI能力融入终端体验

新消费日报

京东商品列表数据接口详解

tbapi

京东API 京东商品列表API 京东数据采集

Mac文件提取工具File Juicer

晨光熹微

GreatSQL从库报错13146:字符集不一致问题处理

GreatSQL

618焕新攻略:华为用户专属全场景智能体验,省钱省心一步到位

最新动态

微擎生态驱动的门店数字化增长

微擎应用市场

Mac应用序列号查找工具Serial Box for mac

晨光熹微

Mac在线视频下载工具Downie for mac

晨光熹微

智能车间管理系统(源码+文档+讲解+演示)

深圳亥时科技

行业专家齐聚 | 共探跨端动态化新态势

京东零售技术

5G-A与AI共舞,广东移动烹出高铁网络加速包

脑极体

AI

火山引擎以实用AI赋能效率跃迁与创作升级,解锁智慧生活新图景

新消费日报

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