欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java從單體架構(gòu)升級(jí)到微服務(wù)要注意的一些問(wèn)題

 更新時(shí)間:2021年04月22日 15:19:54   作者:JiaJian  
這篇文章主要介紹了Java從單體架構(gòu)升級(jí)到微服務(wù)要注意的一些問(wèn)題,對(duì)架構(gòu)感興趣的同學(xué),可以參考下

前言

由于近年來(lái)的移動(dòng)端的發(fā)展和 2C模式 的紅利,一些在風(fēng)口的企業(yè)的業(yè)務(wù)得到爆發(fā)式增長(zhǎng)。從架構(gòu)層面來(lái)說(shuō),業(yè)務(wù)驅(qū)動(dòng)技術(shù)的變革,所以微服務(wù)架構(gòu)的概念得到很多企業(yè)的青睞,因?yàn)榭梢越鉀Q服務(wù)的大流量和高并發(fā)以及穩(wěn)定性的要求。

但是任何架構(gòu)設(shè)計(jì)不是一蹴而就的,不能從起步就開(kāi)始使用微服務(wù),一般都是先通過(guò)單體架構(gòu)來(lái)快速實(shí)現(xiàn)需求和搶占市場(chǎng),然后再迭代式擴(kuò)展。不能一口氣吃個(gè)胖子。

這幾年自己有經(jīng)歷從單體到微服務(wù)的架構(gòu)演變,也有直接參與到已經(jīng)落地的微服務(wù)架構(gòu)的項(xiàng)目中。見(jiàn)過(guò)好的架構(gòu)設(shè)計(jì),也見(jiàn)過(guò)一些孬的設(shè)計(jì)。好的架構(gòu)設(shè)計(jì),代碼結(jié)構(gòu)優(yōu)雅,分層清晰,業(yè)務(wù)邊界劃分明朗,業(yè)務(wù)開(kāi)發(fā)人員職責(zé)清晰。不好的設(shè)計(jì)就會(huì)導(dǎo)致代碼混亂難以維護(hù),對(duì)新需求無(wú)法快速應(yīng)變,開(kāi)發(fā)人員容易在補(bǔ)丁上打補(bǔ)丁,最后造成積重難返不得不重構(gòu)。

架構(gòu)師需要從業(yè)務(wù)層面和未來(lái)業(yè)務(wù)發(fā)展有個(gè)全面的規(guī)劃,讓架構(gòu)高可用,易擴(kuò)展,靈活易使用,隱藏其復(fù)雜性。好的架構(gòu)會(huì)讓下面的業(yè)務(wù)開(kāi)發(fā)人員按照既定的模式“傻瓜式”編程。

既然第一步是單體架構(gòu),那么好的單體架構(gòu)設(shè)計(jì),為我們后期的微服務(wù)拆分會(huì)有事半功倍的效果。避免重復(fù)勞動(dòng)和過(guò)多的重寫(xiě)。我們可以從這些方面進(jìn)行一些有效的設(shè)計(jì)。

劃清業(yè)務(wù)邊界

如果對(duì)未來(lái)的架構(gòu)有微服務(wù)的考慮,那么在單體架構(gòu)的時(shí)候就需要理清業(yè)務(wù)邊界的問(wèn)題,常見(jiàn)的簡(jiǎn)單劃分就是以業(yè)務(wù)區(qū)分,例如:用戶,商品,訂單,支付,權(quán)限等等,具體的拆分程度可根據(jù)自身業(yè)務(wù)量和需要做劃分。

當(dāng)前流行的 DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))可以作為一個(gè)指導(dǎo)原則,但是 DDD 比較偏向于理論,需要執(zhí)行人員有良好的專業(yè)能力才能實(shí)施的比較好。

代碼層次結(jié)構(gòu)

業(yè)務(wù)區(qū)分好之后,就是項(xiàng)目代碼模塊的設(shè)計(jì)。在代碼層我們需要根據(jù)MVC的模式,建議的代碼設(shè)計(jì)層次如下:

├─demo-common
│  │  demo-common.iml
│  │  pom.xml
│  │  
│  └─src
│      ├─main
│      │  ├─java
│      │  └─resources
│      └─test
│          └─java
├─demo-dao
│  │  demo-dao.iml
│  │  pom.xml
│  │  
│  └─src
│      ├─main
│      │  ├─java
│      │  └─resources
│      └─test
│          └─java
├─demo-service
│  │  demo-service.iml
│  │  pom.xml
│  │  
│  └─src
│      ├─main
│      │  ├─java
│      │  └─resources
│      └─test
│          └─java
└─demo-web
    │  demo-web.iml
    │  pom.xml
    │  
    └─src
        ├─main
        │  ├─java
        │  └─resources
        └─test
            └─java

主要包含4個(gè) module 模塊

  • demo-common:基礎(chǔ)模塊,枚舉,常亮類(lèi),工具類(lèi),配置類(lèi)。
  • demo-dao:Dao層,mapper接口,mapper.xml。
  • demo-service:服務(wù)接口提供層,業(yè)務(wù)service接口。
  • demo-web:web層,Controller類(lèi),服務(wù)接口,與外部進(jìn)行交互。

各模塊之間的依賴關(guān)系為:

項(xiàng)目 Module 模塊設(shè)計(jì)完成之后,每個(gè)模塊的內(nèi)部 package 包如何設(shè)計(jì)呢?通常有兩種劃分模式:根據(jù)業(yè)務(wù)模塊然后內(nèi)部按MVC劃分,根據(jù)MVC模式然后內(nèi)部按業(yè)務(wù)劃分。

1、根據(jù)業(yè)務(wù)模塊劃分,就是將每個(gè)業(yè)務(wù)模塊作為一個(gè) package,然后每個(gè)package里面有自己的 MVC,這樣就做到業(yè)務(wù)模塊的隔離。

2、根據(jù) MVC 模式劃分,先根據(jù) MVC模式劃分不同的包,service,serviceImpl,dto等,然后再是各個(gè)業(yè)務(wù)自己的模型和服務(wù)接口。

針對(duì)上述的兩個(gè)劃分模式,個(gè)人的選擇是根據(jù)業(yè)務(wù)模式劃分,這樣的包設(shè)計(jì)與后期微服務(wù)拆分有良好的匹配度,拆分的時(shí)候只需要將每個(gè)業(yè)務(wù)包下的代碼 Copy 到新的微服務(wù)中就行了,易遷移變動(dòng)小。每個(gè)模塊中對(duì)不同的業(yè)務(wù)通過(guò) package 包名進(jìn)行劃分,例如:com.example.jajian.service.order、com.example.jajian.service.user等。

└─src
    ├─main
    │  ├─java
    │  │  └─com
    │  │      └─example
    │  │          └─jajian
    │  │              ├─common
    │  │              │      BaserService.java
    │  │              │      
    │  │              └─service
    │  │                  ├─order
    │  │                  │  ├─dto
    │  │                  │  │      OrderDto.java
    │  │                  │  │      
    │  │                  │  └─service
    │  │                  │      │  OrderService.java
    │  │                  │      │  
    │  │                  │      └─impl
    │  │                  │              OrderServiceImpl.java
    │  │                  │              
    │  │                  ├─pay
    │  │                  │  ├─dto
    │  │                  │  │      PayDto.java
    │  │                  │  │      
    │  │                  │  └─service
    │  │                  │      │  PayService.java
    │  │                  │      │  
    │  │                  │      └─impl
    │  │                  │              PayServiceImpl.java
    │  │                  │              
    │  │                  └─user
    │  │                      ├─dto
    │  │                      │      UserDto.java
    │  │                      │      
    │  │                      └─service
    │  │                          │  UserService.java
    │  │                          │  
    │  │                          └─impl
    │  │                                  UserServiceImpl.java
    │  │                                  
    │  └─resources
    └─test
        └─java

這樣劃分有什么好處?我們單體架構(gòu)的時(shí)候這樣開(kāi)發(fā),當(dāng)需要拆分成微服務(wù)的時(shí)候就可以直接將業(yè)務(wù)包拆分出去,因?yàn)槊總€(gè)業(yè)務(wù)包里面就已經(jīng)包含了所有的當(dāng)前業(yè)務(wù)的關(guān)聯(lián)業(yè)務(wù)類(lèi)。

避免多邊界業(yè)務(wù)的關(guān)聯(lián)查詢

單表關(guān)聯(lián)由于業(yè)務(wù)需要而且簡(jiǎn)單方便易使用,所以多表關(guān)聯(lián)查詢?cè)趩误w服務(wù)中是普遍存在的,如果我們后期不需要做服務(wù)拆分則可以不需要考慮這方面的限制。

但是如果后期有微服務(wù)的規(guī)劃,那么單體服務(wù)的時(shí)候如果沒(méi)有做這個(gè)方面的限制,mybatis 的 mapper.xml中有過(guò)多的多表關(guān)聯(lián)查詢,這些關(guān)聯(lián)查詢會(huì)嚴(yán)重影響服務(wù)拆分的進(jìn)度和復(fù)雜度。

如果同屬于一個(gè)業(yè)務(wù)領(lǐng)域則可以使用關(guān)聯(lián)查詢,而那些微服務(wù)拆分后屬于不同領(lǐng)域的業(yè)務(wù)則應(yīng)避免使用多表關(guān)聯(lián)查詢,因?yàn)椴煌臉I(yè)務(wù)領(lǐng)域后期會(huì)被隔離拆分到不同的服務(wù)當(dāng)中,即數(shù)據(jù)庫(kù)表都是分布在不同的服務(wù)器上,所有服務(wù)之間都是通過(guò)RPC方式進(jìn)行通信,關(guān)聯(lián)查詢這時(shí)是無(wú)法處理的。

Controller層盡量不做業(yè)務(wù)邏輯處理

常看到很多 coder 會(huì)在Controller 層做一些業(yè)務(wù)處理,個(gè)人認(rèn)為這是很不規(guī)范的。Controller層是控制層,是和前端進(jìn)行數(shù)據(jù)轉(zhuǎn)換的,這里我們應(yīng)該只做請(qǐng)求的接受和返回,也無(wú)需做一些異常的try...catch...的捕獲,異常可以通過(guò)全局通用攔截器統(tǒng)一進(jìn)行攔截然后返回給前端異常提示語(yǔ),提升代碼的簡(jiǎn)潔性。

所有的參數(shù)校驗(yàn)也放到 service層,因?yàn)槿绻?wù)內(nèi)部調(diào)用也可以使用提高代碼的共用度。當(dāng)然分層領(lǐng)域模型最好也能區(qū)分開(kāi),

  • DO(Data Object):此對(duì)象與數(shù)據(jù)庫(kù)表結(jié)構(gòu)--對(duì)應(yīng),通過(guò)DAO層向上傳輸數(shù)據(jù)源對(duì)象。
  • DTO(Date Transfer Object):數(shù)據(jù)傳輸對(duì)象,service或Manager向外傳輸?shù)膶?duì)象。
  • VO(View Object):顯示層的對(duì)象,通常是Web向模板渲染引擎層傳輸?shù)膶?duì)象。

這樣區(qū)分開(kāi)的好處是,當(dāng)你需要對(duì)展示層數(shù)據(jù)進(jìn)行特殊定制化的時(shí)候可以靈活變通,例如針對(duì)用戶隱私信息身份證號(hào),手機(jī)號(hào)碼脫敏處理,或者用戶ID加密顯示等。

最后就是統(tǒng)一通用返回類(lèi)了,通過(guò)這種格式的封裝我們將數(shù)據(jù)格式進(jìn)行全局格式化,這里的狀態(tài)碼可以自己設(shè)計(jì)的更詳細(xì)一點(diǎn)。

public class CommonResult<T> {

    public static final String CODE_SUCCESS = "0";
    public static final String CODE_FAILED = "9999";

    private String code;
    private T data;

    private String msg;

    private CommonResult(String code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    public boolean isSuccess() {
        return CODE_SUCCESS.equals(code);
    }

    public static <T> CommonResult<T> success() {
        return new CommonResult<>(CODE_SUCCESS, null, null);
    }

    public static <T> CommonResult<T> success(T data) {
        return new CommonResult<>(CODE_SUCCESS, data, null);
    }

    public static <T> CommonResult<T> success(T data, String msg) {
        return new CommonResult<>(CODE_SUCCESS, data, msg);
    }

    public static <T> CommonResult<T> failed() {
        return new CommonResult<>(CODE_FAILED, null, null);
    }

    public static <T> CommonResult<T> failed(String errorCode, String msg) {
        return new CommonResult<>(errorCode, null, msg);
    }

    public static <T> CommonResult<T> failed(String msg) {
        return new CommonResult<>(CODE_FAILED, null, msg);
    }

    public static <T> CommonResult<T> failed(T data, String msg) {
        return new CommonResult<>(CODE_FAILED, data, msg);
    }

    public static <T> CommonResult<T> failed(String errorCode, T data, String msg) {
        return new CommonResult<>(errorCode, data, msg);
    }
   
   // 省略 setter、getter
}

后記

以上只是列舉了單體服務(wù)未來(lái)規(guī)劃做微服務(wù)時(shí)需要注意的一部分簡(jiǎn)單內(nèi)容,每個(gè)人在做單體架構(gòu)拆分成微服務(wù)的時(shí)候都會(huì)踩到各種各樣的坑,這些坑成了我們的開(kāi)發(fā)經(jīng)驗(yàn),有了這些坑就會(huì)形成注意點(diǎn),在我們下次開(kāi)發(fā)時(shí)就會(huì)具有指導(dǎo)意義。也許我們程序員就是在踩坑和填坑的過(guò)程中成長(zhǎng)壯大起來(lái)的。

以上就是Java從單體架構(gòu)升級(jí)到微服務(wù)要注意的一些問(wèn)題的詳細(xì)內(nèi)容,更多關(guān)于Java的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java行為型模式中命令模式分析

    Java行為型模式中命令模式分析

    在軟件設(shè)計(jì)中,我們經(jīng)常需要向某些對(duì)象發(fā)送請(qǐng)求,但是并不知道請(qǐng)求的接收者是誰(shuí),也不知道被請(qǐng)求的操作是哪個(gè),我們只需在程序運(yùn)行時(shí)指定具體的請(qǐng)求接收者即可,此時(shí)可以使用命令模式來(lái)進(jìn)行設(shè)計(jì)
    2023-02-02
  • Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    本文介紹了Spring Boot中 @KafkaListener 注解的介紹、原理和使用方法,通過(guò)本文的介紹,我們希望讀者能夠更好地理解Spring Boot中 @KafkaListener 注解的使用方法,并在項(xiàng)目中更加靈活地應(yīng)用
    2023-09-09
  • Java編程實(shí)現(xiàn)遍歷兩個(gè)MAC地址之間所有MAC的方法

    Java編程實(shí)現(xiàn)遍歷兩個(gè)MAC地址之間所有MAC的方法

    這篇文章主要介紹了Java編程實(shí)現(xiàn)遍歷兩個(gè)MAC地址之間所有MAC的方法,涉及Java針對(duì)MAC的遍歷獲取與字符串轉(zhuǎn)換相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • SpringBoot實(shí)現(xiàn)定時(shí)發(fā)送郵件的三種方法案例詳解

    SpringBoot實(shí)現(xiàn)定時(shí)發(fā)送郵件的三種方法案例詳解

    這篇文章主要介紹了SpringBoot三種方法實(shí)現(xiàn)定時(shí)發(fā)送郵件的案例,Spring框架的定時(shí)任務(wù)調(diào)度功能支持配置和注解兩種方式Spring?Boot在Spring框架的基礎(chǔ)上實(shí)現(xiàn)了繼承,并對(duì)其中基于注解方式的定時(shí)任務(wù)實(shí)現(xiàn)了非常好的支持,本文給大家詳細(xì)講解,需要的朋友可以參考下
    2023-03-03
  • spring boot 自定義參數(shù)過(guò)濾器,把傳入的空字符轉(zhuǎn)換成null方式

    spring boot 自定義參數(shù)過(guò)濾器,把傳入的空字符轉(zhuǎn)換成null方式

    這篇文章主要介紹了spring boot 自定義參數(shù)過(guò)濾器,把傳入的空字符轉(zhuǎn)換成null方式。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring實(shí)戰(zhàn)之使用p:命名空間簡(jiǎn)化配置操作示例

    Spring實(shí)戰(zhàn)之使用p:命名空間簡(jiǎn)化配置操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之使用p:命名空間簡(jiǎn)化配置操作,結(jié)合實(shí)例形式分析了spring p:命名空間簡(jiǎn)單配置與使用操作技巧,需要的朋友可以參考下
    2019-12-12
  • java版十大排序經(jīng)典算法:完整代碼(4)

    java版十大排序經(jīng)典算法:完整代碼(4)

    優(yōu)秀的文章也不少,但是Java完整版的好像不多,我把所有的寫(xiě)一遍鞏固下,同時(shí)也真誠(chéng)的希望閱讀到這篇文章的小伙伴們可以自己去從頭敲一遍,不要粘貼復(fù)制!希望我的文章對(duì)你有所幫助,每天進(jìn)步一點(diǎn)點(diǎn)
    2021-07-07
  • Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)的實(shí)例代碼

    Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)的實(shí)例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Netty與Spring Boot的整合實(shí)現(xiàn)

    Netty與Spring Boot的整合實(shí)現(xiàn)

    這篇文章主要介紹了Netty與Spring Boot的整合的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 阿里的一道Java并發(fā)面試題詳解

    阿里的一道Java并發(fā)面試題詳解

    這篇文章主要介紹了阿里的一道Java并發(fā)面試題詳解,網(wǎng)絡(luò)、并發(fā)相關(guān)的知識(shí),相對(duì)其他一些編程知識(shí)點(diǎn)更難一些,主要是不好調(diào)試并且涉及內(nèi)容太多 !,需要的朋友可以參考下
    2019-06-06

最新評(píng)論