作者:小傅哥

博客: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. 某拍sig算法揭秘---50行代码下载5000万小姐姐自拍小视频

    背景: ​ ​ ​ 首先我们需要一点点python基础,比如可以运行类似下面的代码 import requests headers={ "xxx":"xxx", ...

  2. Firefox 66 发布,阻止网站自动播放声音

    Firefox 66 发布了,此版本在桌面版中带来的新特性包括: Firefox 现在阻止网站自动播放声音,如果需要可以单独调整 改进的搜索体验: 当打开许多选项卡时,可以更快地查找特定网页:现在可以 ...

  3. xml文件错误

    2019独角兽企业重金招聘Python工程师标准>>> xml文件错误The processing instruction target matching "[xX][mM ...

  4. 如何在linux服务器下快速安装配置Node.js

    简单粗暴,先用xshell或其他软件连接服务器 1.下载(此处版本根据官网版本自己修改) wget https://npm.taobao.org/mirrors/node/v8.9.3/node-v8 ...

  5. RHEL6 搭建 keepalived + lvs/DR 集群

    搭建 keepalived + lvs/DR  集群 使用Keepalived为LVS调度器提供高可用功能,防止调度器单点故障,为用户提供Web服务: LVS1调度器真实IP地址为192.168.4. ...

  6. 数学--数论--欧拉降幂--P5091 欧拉定理

    题目背景 出题人也想写有趣的题面,可惜并没有能力. 题目描述 给你三个正整数,a,m,ba,m,ba,m,b,你需要求:ab mod ma^b \bmod mabmodm 输入格式 一行三个整数,a, ...

  7. Codeforces Round #618 (Div. 2)-B. Assigning to Classes

    Reminder: the median of the array [a1,a2,-,a2k+1] of odd number of elements is defined as follows: l ...

  8. 数学--数论--HDU 2674 沙雕题

    WhereIsHeroFrom: Zty, what are you doing ? Zty: I want to calculate N!.. WhereIsHeroFrom: So easy! H ...

  9. CSS设计超链接样式

    \(\color{Red}{首先设计一下静止的a标签}\) a{ margin-right:10px;/*右边距,其他边距同理*/ border-bottom:1px solid #eec/*分别是下 ...

  10. 完全背包和多重背包的混合 F - The Fewest Coins

    http://poj.org/problem?id=3260 这个题目有点小难,我开始没什么头绪,感觉很乱. 后来看了题解,感觉豁然开朗. 题目大意:就是这个人去买东西,东西的价格是T,这个人拥有的纸 ...