当DDD遇上微服务

DDD与微服务是可以相通的,其关键在于Bounded Context。

分布式系统的定义

在谈论这个之前,我们需要就什么是分布式系统达成一致。在我看来,判断一个系统是否是分布式的,其标准是看系统中是否存在跨进程通信。是进程决定了协作与通信的方式,从而引申出两种具有本质区别的编程模型:

  • 进程内编程模型
  • 跨进程编程模型

它们之间的区别在于组件之间的调用方式。进程内的组件调用是非常简单的,就Java而言,各个驻留于同一个JVM的对象与变量都放在堆内存或者栈内存中,对象的调用(包括方法的调用)就是一种内存的寻址。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遇到微服务,其实有许多玄妙的相似之处值得深究。它们之间或许可以碰撞出感情的火花,也未可知呢。

原文发布于微信公众号 - 逸言(YiYan_OneWord)

原文发表时间:2017-08-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CSDN技术头条

Hamsterdb vs. LevelDB:且看非主流数据库的自白和逆袭

【编者按】虽已问世9年之久,但是相较MongoDB,Hamsterdb的知名度仍然有所欠缺,更一度被评为非主流数据库。Hamsterdb是个开源的键值类型数据库...

2077
来自专栏牛客网

安卓工程师:秋招21家公司的面试真题总结

之前一直混迹于牛客,现在也反馈一波给牛油们。下面是秋招的面试经历具体内容。 拼多多 学霸提前批Android研发工程师 offer 笔试 基于给定接口实现Ima...

6316
来自专栏飞总聊IT

Log:被BigData遗忘的奠基者

Log是关系数据库对计算机行业的伟大贡献。在大数据时代,Log更是基础技术之一。然而在大家热烈讨论GFS, NoSQL,乃至Paxos, LSM tree等词语...

3567
来自专栏Python中文社区

用Python玩转微信的正确姿势!

0. itchat 最近研究了一些微信的玩法,我们可以通过网页版的微信微信网页版,扫码登录后去抓包爬取信息,还可以post去发送信息。 然后发现了itchat这...

5018
来自专栏Golang语言社区

在 Go 语言中,如何正确的使用并发

从多个花絮中提取,但是如果我斗胆提出主要观点的总结,其内容就是:抢占式多任务和一般共享状态结合导致软件开发过程不可管理的复杂性, 开发人员可能更喜欢保持自己的一...

1092
来自专栏大数据挖掘DT机器学习

股票数据API整理

最近在做股票分析系统,数据获取源头成了一大问题,经过仔细的研究发现了很多获取办法,这里整理一下,方便后来者使用。 获取股票数据的源头主要有:数据超市、雅虎、新...

2.2K7
来自专栏Java技术

初探性能优化--2个月到4小时的性能提升!

一直不知道性能优化都要做些什么,从哪方面思考,直到最近接手了一个公司的小项目,可谓麻雀虽小五脏俱全。让我这个编程小白学到了很多性能优化的知识,或者说一些思考方式...

681
来自专栏Jerry的SAP技术分享

腾讯AI开放平台的接口调用指南

最近无意发现腾讯AI开放平台上提供了大量好玩的人工智能云服务,而且是完全免费的。只需要用QQ号登录即可。这么好的东西,作为一个程序员,当然要试试了!

9602
来自专栏牛客网

2018腾讯、美团C++后台研发实习生面经

2190
来自专栏数据结构与算法

万能pb_ds头文件—bits/extc++.h

c++中自带了一些非常强大却鲜为人知的功能库—pd_ds库 里面含有红黑树(rb_tree),哈希表(gp_hash_table),可持久化平衡树(rope)等...

3626

扫码关注云+社区