作者:小傅哥

博客:https://bugstack.cn

沉淀、分享、成长,让自己和他人都能有所收获!

一、前言介绍

微服务不是泥球小单体,而是具备更加清晰职责边界的完整一体的业务功能服务。领域驱动设计的思想通过Domain的功能域设计,可以把核心功能与支撑功能很好的区分开。而在MVC的设计模式尝尝是把所有的;数据服务、定义的属性类、提供的功能都在一条线上,这样是非常快速的开发方式但在做微服务部署时候确很麻烦。

按照不同的业务场景可能设计出软件在数据库使用上会有单库单表或者分库分表,如果是一个体量足够需要分库分表设计的系统,在扩容时候它是否能满足你的需求包括;

  1. 核心计算不涉及库扩容,但是系统功能都在一起怎么办,已扩容都扩容了很浪费
  2. 所有的扩容都涉及到数据库连接数增加,但并不是每个行为都直达到所有库表
  3. 持续发展的业务会带来数据激增,将来怎么进行扩展,重新洗数据并不是很好的选择

那么实际开发大泥球架构时,不只是会遇到上面的问题,还可能会遇到工期很赶加个人也不提升效率,反复交接代码扶不过三代等等,因此我们将服务拆分为独立单体具备此核心域完整功能的系统是非常必要的。

如图,是微服务数据库使用的一种思想,我们希望路由层从最开始就被执行,用户分群动态扩展

二、案例目标

本案例通过使用SpringCloud将我们的服务架构扩展为通过路由调用的微服务

  1. 首先通过Eureka作为服务注册与发现中心
  2. 然后使用Feign模式作为调用API接口
  3. 最后依赖于zuul设置路由转发功能

为了方便测试,本案例会在itstack-demo-ddd-03中建4个工程;

itstack-demo-ddd-case{基于DDD的微服务}

itstack-demo-ddd-eureka-server{服务注册与发现}

itstack-demo-ddd-feign{调用方,通过API接口调用}

itstack-demo-ddd-zuul{网关路由组件}

三、开发环境

  1. jdk1.8
  2. springboot 2.0.6.RELEASE 以及SpringCloud相关服务
  3. idea + maven

四、代码示例

1. itstack-demo-ddd-case | 基于DDD的微服务 {本段代码在上一章节已经演示}

itstack-demo-ddd-case
└── src
├── main
│ ├── java
│ │ └── org.itstack.demo
│ │ ├── application
│ │ │ ├── MallRuleService.java
│ │ │ └── MallTreeService.java
│ │ ├── domain
│ │ │ ├── rule
│ │ │ │ ├── model
│ │ │ │ │ ├── aggregates
│ │ │ │ │ │ └── UserRichInfo.java
│ │ │ │ │ └── vo
│ │ │ │ │ ├── DecisionMatter.java
│ │ │ │ │ ├── EngineResult.java
│ │ │ │ │ ├── TreeNodeInfo.java
│ │ │ │ │ ├── TreeNodeLineInfo.java
│ │ │ │ │ └── UserSchool.java
│ │ │ │ ├── repository
│ │ │ │ │ └── IRuleRepository.java
│ │ │ │ └── service
│ │ │ │ ├── engine
│ │ │ │ │ ├── impl
│ │ │ │ │ └── EngineFilter.java
│ │ │ │ ├── logic
│ │ │ │ │ ├── impl
│ │ │ │ │ └── LogicFilter.java
│ │ │ │ └── MallRuleServiceImpl.java
│ │ │ └── tree
│ │ │ ├── model
│ │ │ │ ├── aggregates
│ │ │ │ │ └── TreeCollect.java
│ │ │ │ └── vo
│ │ │ │ ├── TreeInfo.java
│ │ │ │ └── TreeRulePoint.java
│ │ │ ├── repository
│ │ │ │ └── ITreeRepository.java
│ │ │ └── service
│ │ │ └── MallTreeServiceImpl.java
│ │ ├── infrastructure
│ │ │ ├── common
│ │ │ │ └── Constants.java
│ │ │ ├── dao
│ │ │ │ ├── RuleTreeDao.java
│ │ │ │ ├── RuleTreeNodeDao.java
│ │ │ │ └── RuleTreeNodeLineDao.java
│ │ │ ├── po
│ │ │ │ ├── RuleTree.java
│ │ │ │ ├── RuleTreeConfig.java
│ │ │ │ ├── RuleTreeNode.java
│ │ │ │ └── RuleTreeNodeLine.java
│ │ │ ├── repository
│ │ │ │ ├── cache
│ │ │ │ │ └── RuleCacheRepository.java
│ │ │ │ ├── mysql
│ │ │ │ │ ├── RuleMysqlRepository.java
│ │ │ │ │ └── TreeMysqlRepository.java
│ │ │ │ ├── RuleRepository.java
│ │ │ │ └── TreeRepository.java
│ │ │ └── util
│ │ │ └── CacheUtil.java
│ │ ├── interfaces
│ │ │ ├── dto
│ │ │ │ ├── DecisionMatterDTO.java
│ │ │ │ └── TreeDTO.java
│ │ │ └── DDDController.java
│ │ └── DDDApplication.java
│ └── resources
│ ├── mybatis
│ └── application.yml
└── test
└── java
└── org.itstack.demo.test
└── ApiTest.java

2. itstack-demo-ddd-eureka-server | 服务注册与发现

itstack-demo-ddd-eureka-server
└── src
├── main
│ ├── java
│ │ └── org.itstack.demo
│ │ └── EurekaServerApplication.java
│ └── resources
│ └── application.yml
└── test
└── java
└── org.itstack.demo.test
└── ApiTest.java

EurekaServerApplication.java | 启动服务

/**
* 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例
* 论坛:http://bugstack.cn
* Create by 小傅哥 on @2019
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication { public static void main(String[] args) {
SpringApplication.run( EurekaServerApplication.class, args );
} }

application.yml | 服务配置

server:
port: 8989 eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ spring:
application:
name: itstack-demo-ddd-eureka-server

3. itstack-demo-ddd-feign | 调用方,通过API接口调用

itstack-demo-ddd-feign
└── src
├── main
│ ├── java
│ │ └── org.itstack.demo
│ │ ├── domain
│ │ │ └── TreeDTO.java
│ │ ├── service
│ │ │ └── MallService.java
│ │ ├── web
│ │ │ └── FeignController.java
│ │ └── FeignApplication.java
│ └── resources
│ └── application.yml
└── test
└── java
└── org.itstack.demo.test
└── ApiTest.java

MallService.java | 通过注册方式调用API

/**
* 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例
* 论坛:http://bugstack.cn
* Create by 小傅哥 on @2019
*/
@FeignClient(value = "itstack-demo-ddd-case")
public interface MallService { @RequestMapping(value = "/api/tree/queryTreeSummaryInfo", method = RequestMethod.POST)
Object queryTreeSummaryInfo(@RequestBody TreeDTO request); }

FeignApplication.java | 启动服务

/**
* 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例
* 论坛:http://bugstack.cn
* Create by 小傅哥 on @2019
*/
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication { public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
} }

application.yml | 服务配置

server:
port: 9090 spring:
application:
name: itstack-demo-ddd-feign eureka:
client:
serviceUrl:
defaultZone: http://localhost:8989/eureka/

4. itstack-demo-ddd-zuul| 网关路由组件

itstack-demo-ddd-zuul
└── src
├── main
│ ├── java
│ │ └── org.itstack.demo
│ │ └── ZuulApplication.java
│ └── resources
│ └── application.yml
└── test
└── java
└── org.itstack.demo.test
└── ApiTest.java

ZuulApplication.java | 启动服务

/**
* 微信公众号:bugstack虫洞栈 | 专注原创技术专题案例
* 论坛:http://bugstack.cn
* Create by 小傅哥 on @2019
*/
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
@EnableDiscoveryClient
public class ZuulApplication { public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
} }

application.yml | 服务配置{本案例是静态路由,按需可以开发为动态路由}

server:
port: 9191 spring:
application:
name: itstack-demo-ddd-zuul eureka:
client:
serviceUrl:
defaultZone: http://localhost:8989/eureka/
zuul:
routes:
api-a:
path: /route-a/**
serviceId: itstack-demo-ddd-feign

五、测试验证

按照顺序启动;itstack-demo-ddd-eureka-server、itstack-demo-ddd-case{可以模拟启动多个}、itstack-demo-ddd-feign、itstack-demo-ddd-zuul

访问;http://localhost:8989/ | 服务中心

访问:http://localhost:9191/route-a/api/queryTreeSummaryInfo?treeId=10001 | 通过网关路由调用DDD服务接口

六、综上总结

  1. DDD的设计模式加上SpringBoot与SpringCloud非常适合开发微服务
  2. 以上案例可以进行扩展,使不同的用户群体在网关接口调用时就打到不同的服务上
  3. 另外目前没有使用dubbo类型的rpc框架,也就是没有对外提供定义接口jar包,后续会进行延展

七、推荐阅读

Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务的更多相关文章

  1. 基于Spring-Cloud的微服务框架设计

    基于Spring-Cloud的微服务框架设计 先进行大的整体的框架整理,然后在针对每一项进行具体的详细介绍

  2. 领域驱动设计实战—基于DDDLite的权限管理OpenAuth.net

    在园子里面,搜索一下“权限管理”至少能得到上千条的有效记录.记得刚开始工作的时候,写个通用的权限系统一直是自己的一个梦想.中间因为工作忙(其实就是懒!)等原因,被无限期搁置了.最近想想,自己写东西时, ...

  3. DDD领域驱动设计架构模式:防腐层(Anti-corruption layer)

    在微服务(Microservices)架构实践中,架构设计借用了DDD中的一些概念和技术,比如一个微服务对应DDD中的一个限界上下文(Bounded Context):在微服务设计中应该首先识别出DD ...

  4. 基于SpringCloud的微服务架构实战案例项目,以一个简单的购物流程为示例

    QuickStart 基于SpringCloud体系实现,简单购物流程实现,满足基本功能:注册.登录.商品列表展示.商品详情展示.订单创建.详情查看.订单支付.库存更新等等. 每个业务服务采用独立的M ...

  5. 基于SpringCloud的微服务架构实战案例项目

    QuickStart 基于SpringCloud体系实现,简单购物流程实现,满足基本功能:注册.登录.商品列表展示.商品详情展示.订单创建.详情查看.订单支付.库存更新等等. github源码地址:h ...

  6. Java开发架构篇《初识领域驱动设计DDD落地》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 DDD(Domain-Driven Design 领域驱动设计)是由Eric Eva ...

  7. 如何使用ABP进行软件开发(2) 领域驱动设计和三层架构的对比

    简述 上一篇简述了ABP框架中的一些基础理论,包括ABP前后端项目的分层结构,以及后端项目中涉及到的知识点,例如DTO,应用服务层,整洁架构,领域对象(如实体,聚合,值对象)等. 笔者也曾经提到,AB ...

  8. 领域驱动设计(Domain Driven Design)参考架构详解

    摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...

  9. [转载]领域驱动设计(Domain Driven Design)参考架构详解

    摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...

随机推荐

  1. innobackupex 出现Unrecognized character \x01; marked by

    centos 7.2 mysql 5.7.16 innobackupex version 2.4.6 [root@Devops-mysql-150-115 sh]# innobackupex --de ...

  2. Flutter仿网易云音乐:播放界面

    写在前头 本来是要做一个仿网易云音乐的flutter项目,但是因为最近事情比较多,项目周期跨度会比较长,因此分几个步骤来完成.这是仿网易云音乐项目系列文章的第一篇.没有完全照搬网易云音乐的UI,借鉴了 ...

  3. 一只简单的网络爬虫(基于linux C/C++)————支持动态模块加载

    插件在软件设计中有很大的好处,可以方便地扩展各种功能,使用插件技术能够在分析.设计.开发.项目计划.协作生产和产品扩展等很多方面带来好处: (1)结构清晰.易于理解.由于借鉴了硬件总线的结构,而且各个 ...

  4. Python基础03 id

    id id(x)对应变量x所引用对象的内存地址.可以把id(x)看成变量x的身份标识. is 有时在编程中需要与变量的身份标识打交道,但不是通过 id 函数,而是 is 操作符. The operat ...

  5. K. Road Widening

    \(考虑每个区域可行的区间\) \(x[1]=s[1]\ \ y[1]=s[1]+g[1]\) \(x[i]=max(x[i-1]-1,s[i]),y[i]=min(y[i-1]+1,s[i]+g[i ...

  6. 网络流二十四题,题解summary

    没有全部写完,有几题以后再补吧. 第一题:最简单的:飞行员配对方案问题 讲讲这个题目为什么可以用网络流? 因为这个题目是要进行两两之间的匹配,这个就可以想到用二分图匹配,二分图匹配又可以用网络流写. ...

  7. H - Food HDU - 4292 网络流

    题目   You, a part-time dining service worker in your college’s dining hall, are now confused with a n ...

  8. 系统基础优化 vim

    系统基础优化 vim 1系统基础优化 (CPU-lscpu 内存-free 磁盘-df 负载-w/uptime) 1.1 系统基础优化 准备工作:如何查看系统的信息 (1)cat /etc/redha ...

  9. Oracle触发器之替代触发器

    替代触发器 替代视图增删改操作.视图可以认为成逻辑上的一张表,类似于把一个sql语句的执行结果永久的像表存储到数据 库中,视图一般用来做查询. 创建视图的语法: create view 视图名称 as ...

  10. 最终父类【根类】:Object类&Objects类

    一.java.lang.Object类 1.Object类介绍 Object类是所有类的父类.一个类都会直接或间接继承自该类: ​ 该类中提供了一些非常常用的方法! 2.toString()方法 A: ...