我在"微服务之间的最佳调用方式"中讲到了微服务之间的两种调用方式。微服务刚兴起时,大部分都是RPC的调用模式。我也写了一个RPC的架构,详情参见"清晰架构(Clean Architecture)的Go微服务"。但现在事件驱动的微服务越来越流行,因为大家觉得它是松耦合的。我会写一个新的系列来讲述如何构建事件驱动的微服务。本文是这个系列的第一篇,总体设计。
本文通过一个具体的例子来讲解事件驱动微服务的设计,它包含两个微服务,一个是订单服务(Order),另一个是支付服务(Payment),它们各自独立,每个服务有自己的源码库,数据库,各自单独部署。它们之间通过事件驱动的方式互相调佣。
在拿到一个新的项目时,我们有时会觉得不知道从哪下手。最通常的的思路是化繁为简,把一个大的项目分解为一个个小的部分再各个击破。把程序分层也是这个思路的具体应用。这里我们仍然沿用RPC时的架构,按照清晰架构把业务逻辑分成三层,域模型(model),用例(usecase)和数据服务(dataservice)。在事件驱动模式时会增加新的层,就是事件层(Event),它包含事件和事件驱动器(Event Handler)。在本文中,你将会读到如何对原来的架构进行扩展,增加事件处理功能。
本文从下面三个方面讲解程序的设计:
- 模块设计
- 框架(Framework)和库(Library)
- 共享程序和第三方库
它们是设计中最基本的也是最重要的东西,有了它其他的东西才能在这个基础之上建立起来。
模块设计:
程序设计中的很重要的一步就是把程序的功能拆分成小的模块,并把程序分层,然后把这些模块放入相应的层级,最后确立模块之间的依赖关系。
程序分层
本程序基本延用了清晰架构的原则,但由于增加了事件驱动的部分,因此我引入了"Domain-Driven Design"的一些概念对清晰架构进行了一些改造。毕竟事件驱动的很多概念都是由DDD(Domain-Driven Design)提出来的,它有关于事件驱动的一整套理论和实践。对于DDD的理解,不同的人的解释可能稍有差别,其中最著名的应该来自于Eric Evans的书"Domain-Driven Design: Tackling Complexity in the Heart of Software"。但因为它稍微有一点虚,有些概念并没有明确的代码,因此可能会有不同的解读。由于这个原因,我采用了"Patterns, Principles, and Practices of Domain-Driven Design"这本书中对DDD的解释,它里面所有的概念都有具体的代码和实例,全部都是落了地的东西,这样至少不会产生歧义。
在“Pattern,Principles,and Practices of Domain-Driven Design”这本书中,它列举了DDD的8个组成模块,它们是值对象(Value Object),实体(Entities),域服务(Domain Service),域事件(Domain Event),聚合根(Aggregates),工厂(Factories),仓