当DDD遇上微服务
DDD与微服务是遇上可以相通的,其关键在于Bounded Context。微服务
分布式系统的遇上定义
在谈论这个之前,我们需要就什么是微服务分布式系统达成一致。在我看来,遇上判断一个系统是微服务否是分布式的,其标准是遇上看系统中是否存在跨进程通信。是微服务进程决定了协作与通信的方式,从而引申出两种具有本质区别的遇上编程模型:
进程内编程模型 跨进程编程模型它们之间的区别在于组件之间的调用方式。进程内的微服务组件调用是非常简单的,就Java而言,遇上各个驻留于同一个JVM的微服务对象与变量都放在堆内存或者栈内存中,对象的遇上调用(包括方法的调用)就是一种内存的b2b供应网寻址。Java语言通过new关键字创建实例,微服务从而获得该实例的遇上指针,以便于对该实例的属性与方法进行调用。
跨进程组件之间的调用方式与进程内调用有着本质的。虽然跨进程通信机制存在各种不同的实现,但它们要考量的因素都是相同的,需要考虑:
进程间的通信协议 如何寻址 消息的序列化与反序列化除此之外,在资源管理、事务一致性以及部署方面,都会因为跨进程通信的原因而产生巨大的差别。
显然,跨进程通信固有的复杂度带来了编程模型的改变,但它能够更加有效地利用硬件资源,却是分布式系统的主要目标。因此,在IT发展的站群服务器当前历史背景下,我们将进程作为边界来定义分布式系统是非常有意义的。
说明:不同的语言平台,进程的概念有细微差别,通信机制自然也有所不同。Java进程等同于操作系统的进程,但Erlang与Go的进程概念则不相同,要更加轻量级。
跨进程组件之间的调用方式其实是对通信机制的一种抽象,它其实又包含了:
进程间通信机制(如共享内存、管道、Socket) 结构化通信机制(如RPC) 中间件通信机制(分布式对象如CORBA、组件中间件如EJB、消息中间件、面向服务与REST)讨论C4模型的Container
Simon Brown提出了自己的C4模型,如下图所示:

我们对Container的划分,可以将进程作为划分的边界,即我认为的“物理边界”。所以Container在架构中除了可以作为逻辑视图的亿华云计算组成元素之外,也可以视为物理视图的一部分。
无独有偶,Alistair Cockburn提出的六边形架构(又名port-adapter模式)在边界含义上与Container是与之呼应的。下图中外部六边形的边界就是一个物理边界,按照之前的分析,我们可以将其视为进程边界。

微服务与Bounded Context
微服务作为一个可以独立部署的微小服务,天生就是一个在物理上隔离的自治服务。从物理视图的角度看,一个微服务就是C4模型中的Container,也就是六边形架构中的六边形。如果我们将六边形架构与DDD的Bounded Context对应起来,那么就可以引入DDD的战略设计来划分服务边界,从而帮助我们进行微服务设计了。
一个典型的Bounded Context,可以具有自己的领域模型,访问专有的数据库,且可以引入“依赖注入”来满足Uncle Bob所谓的Clean Architecture思想。下图所示的Bounded Context的架构,不正是可以表现为一个微服务吗?

Context Map对微服务的阐释
思考DDD中的Bounded Context,可以重点把握以下两点:
Bounded Context与Domain之间的关系 Context Map倘若我们认为Bounded Context与Domain之间存在对应关系,就说明可以从业务架构的层面来设计微服务。通过用例、通用语言或者其他手段,都可以帮助我们识别Bounded Context,进而得到相对合理的服务边界。
若要判断微服务的设计是否合理,则可以通过DDD的Context Map进一步验证和判别Bounded Context的划分,并理清楚它们之间的关系。
Eric Evans在DDD一书中列出了九种Context Map,基本上可以归类为:
团队之间的协作方式 进程之间的集成方式为什么说Bounded Context之间的关系可以理解为是团队之间的协作方式呢?理论根据来自康威定律,即:
设计一个系统(此处泛指更广泛的系统,而不仅仅是信息系统)的任何组织都必然会产生一个其结构是该组织通信结构副本的设计。一个Bounded Context可能会映射到一个开发团队,所以讨论Bounded Context之间的关系,也可以视为是讨论团队之间的关系。至于进程之间的集成方式,无论是引入ACL(防腐层)还是OHS(开放主机服务),目的都是在实现进程间通信的同时,更好地做到Bounded Context之间的松散耦合。以微服务观之,就是要满足服务边界足够的自治性。
故而当DDD遇到微服务,其实有许多玄妙的相似之处值得深究。它们之间或许可以碰撞出感情的火花,也未可知呢。
【本文为专栏作者“张逸”原创稿件,转载请联系原作者】
戳这里,看该作者更多好文
相关文章
- 摘要:电脑机箱是计算机硬件的重要组成部分,它不仅起到保护内部硬件的作用,还能有效散热。然而,许多人在使用电脑时犯了一个致命错误——让电脑机箱一直开着。本文将介绍这个常见的错误以及由此带来...2025-11-05
pyc 文件的触发上一篇文章我们介绍了字节码,当时提到,py 文件在执行的时候会先被编译成 PyCodeObject 对象,并且该对象还会被保存到 pyc 文件中。然而事实并不总是这样,有时当我们运行2025-11-05- 复制//input设备对象 structinput_dev{ constchar*name; unsignedlongevbit[BI2025-11-05
数据持久化是指将数据从内存中,保存到磁盘或其他持久存储介质的过程,这样做的目的是为了保证数据不丢失。而 Redis 的持久化功能默认是开启的,这样做的目的也是为了保证程序的稳定性防止缓存雪崩、缓存击穿2025-11-05SSG战队(探索SSG战队的辉煌征程,以及其取得的成就和荣誉)
摘要:SSG战队作为电子竞技界的佼佼者,以其出色的实力和卓越的团队合作精神,一直在顶级比赛中占据着主导地位。本文将带领读者一起回顾SSG战队的崛起历程,并分析其成功的关键因素。从...2025-11-05
在.NET中通过官方Logging将日志保存到数据库方法(以MySQL为例)
在.NET中,Microsoft.Extensions.Logging是一个灵活的日志库,它允许你将日志信息记录到各种不同的目标,包括数据库。在这个示例中,我将详细介绍如何使用Microsoft.Ex2025-11-05

最新评论