Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务

Wesley13
• 阅读 486

作者:小傅哥
博客:https://bugstack.cn

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

一、前言介绍

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

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

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

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

如图,是微服务数据库使用的一种思想,我们希望路由层从最开始就被执行,用户分群动态扩展
Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务

二、案例目标

本案例通过使用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/ | 服务中心
Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务

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

Java开发架构篇:领域驱动设计架构基于SpringCloud搭建微服务

六、综上总结

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

七、推荐阅读

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小傅哥 小傅哥
3年前
半年招聘筛选了400+份简历,告诉你怎么写容易被撩!
作者:小傅哥博客:https://bugstack.cn(https://bugstack.cn)沉淀、分享、成长,让自己和他人都能有所收获!😄
小傅哥 小傅哥
4年前
一次代码评审,差点过不了试用期!
作者:小傅哥博客:https://bugstack.cn(https://bugstack.cn)沉淀、分享、成长,让自己和他人都能有所收获!😄一
小傅哥 小傅哥
4年前
设计模式PDF下载了4.0万本!那,再肝一本《Java面经手册》吧!
作者:小傅哥博客:https://bugstack.cn(https://bugstack.cn)沉淀、分享、成长,让自己和他人都能有所收获!😄一
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
小傅哥 小傅哥
4年前
握草,你竟然在代码里下毒!
作者:小傅哥博客:https://bugstack.cn(https://bugstack.cn)沉淀、分享、成长,让自己和他人都能有所收获!😄
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这