Java開發架構篇:領域驅動設計架構基於SpringCloud搭建微服務

做者:小傅哥
博客:https://bugstack.cnhtml

沉澱、分享、成長,讓本身和他人都能有所收穫!

1、前言介紹

微服務不是泥球小單體,而是具有更加清晰職責邊界的完整一體的業務功能服務。領域驅動設計的思想經過Domain的功能域設計,能夠把核心功能與支撐功能很好的區分開。而在MVC的設計模式嚐嚐是把全部的;數據服務、定義的屬性類、提供的功能都在一條線上,這樣是很是快速的開發方式但在作微服務部署時候確很麻煩。java

按照不一樣的業務場景可能設計出軟件在數據庫使用上會有單庫單表或者分庫分表,若是是一個體量足夠須要分庫分表設計的系統,在擴容時候它是否能知足你的需求包括;mysql

  1. 核心計算不涉及庫擴容,可是系統功能都在一塊兒怎麼辦,已擴容都擴容了很浪費
  2. 全部的擴容都涉及到數據庫鏈接數增長,但並非每一個行爲都直達到全部庫表
  3. 持續發展的業務會帶來數據激增,未來怎麼進行擴展,從新洗數據並非很好的選擇

那麼實際開發大泥球架構時,不僅是會遇到上面的問題,還可能會遇到工期很趕加我的也不提高效率,反覆交接代碼扶不過三代等等,所以咱們將服務拆分爲獨立單體具有此核心域完整功能的系統是很是必要的。web

如圖,是微服務數據庫使用的一種思想,咱們但願路由層從最開始就被執行,用戶分羣動態擴展
微信公衆號:bugstack蟲洞棧 | 微服務數據庫路由spring

2、案例目標

本案例經過使用SpringCloud將咱們的服務架構擴展爲經過路由調用的微服務sql

  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{網關路由組件}數據庫

3、開發環境

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

4、代碼示例

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

5、測試驗證

按照順序啓動;itstack-demo-ddd-eureka-server、itstack-demo-ddd-case{能夠模擬啓動多個}、itstack-demo-ddd-feign、itstack-demo-ddd-zuul設計模式

訪問; http://localhost:8989/ | 服務中心
微信公衆號:bugstack蟲洞棧 | 服務中心

訪問:http://localhost:9191/route-a/api/queryTreeSummaryInfo?treeId=10001 | 經過網關路由調用DDD服務接口api

微信公衆號:bugstack蟲洞棧 | 調用網關接口測試

6、綜上總結

  1. DDD的設計模式加上SpringBoot與SpringCloud很是適合開發微服務
  2. 以上案例能夠進行擴展,使不一樣的用戶羣體在網關接口調用時就打到不一樣的服務上
  3. 另外目前沒有使用dubbo類型的rpc框架,也就是沒有對外提供定義接口jar包,後續會進行延展

7、推薦閱讀

相關文章
相關標籤/搜索