1. 程式人生 > >搭建基於springboot輕量級讀寫分離開發框架

搭建基於springboot輕量級讀寫分離開發框架

#何為讀寫分離 讀寫分離是指對資源的修改和讀取進行分離,能解決很多資料庫瓶頸,以及程式碼混亂難以維護等相關的問題,使系統有更好的擴充套件性,維護性和可用性。 一般會分三個步驟來實現: 一. 主從資料庫搭建 資訊管理系統的絕大部分瓶頸在資料庫,通過搭建主從資料庫,寫到主資料庫,讀取從資料庫,提高資料庫的吞吐量,根據業務需求可以搭建一主一從、一主多從的資料庫同步架構。如果報表多的系統,可以搭個一主多從架構,一個從資料庫供普通查詢,另一個從資料庫供報表查詢,這樣能夠避免報表的複雜查詢影響客戶正常操作。 二. 讀寫程式碼分離 程式碼上對讀寫進行分離。讀的邏輯相對簡單,幾乎不需要做過多的分層封裝。大部分業務邏輯在寫操作,所以我們需要專注於對寫程式碼的分層、抽象封裝。注意: 在寫模組涉及到業務資料讀取,幾乎要實時的,而且基於高內聚的原則,應該封裝進寫程式碼類中,讀取主資料庫。 三. 程序分離 將讀和寫的程式碼封裝到不同的程序,從程序級別避免相互影響,其實就是分散式。實現從程序上解耦,程式執行期間的效能、異常錯誤不會相互影響,所以系統有相對高的可用性。 這裡多說一句, 如果對寫業務按領域拆分到不同的程序,會涉及到分散式事務,在未涉及到高併發、大資料的系統,其實沒必要從程序上拆分,分散式對事務不友好,為了處理分散式事務,你需要付出更多的時間和金錢成本。考慮程序拆分,一定要基於實際業務需求再三權衡利弊。很多時候,也許你只需要多一個從資料庫、一個快取、多一臺伺服器、多幾G記憶體、多幾核cpu、優化一下sql 即可解決很多效能上的問題。 #如何搭建 現在我們搭建一主一從資料庫架構, 並且實現從程式碼上進行讀寫分離的開發框架,但不涉及程序分離。 ## 1. 搭建主從資料庫 mariadb 可參考[搭建 mariadb 資料庫主從同步](https://www.cnblogs.com/grissom007/p/14368831.html) 或者 [https://mariadb.com/kb/en/setting-up-replication/](https://mariadb.com/kb/en/setting-up-replication/) 。 ## 2. 基於springboot 搭建開發框架 ### 2.1 專案結構 畫一下框架的模組結構 ![](https://img2020.cnblogs.com/blog/488490/202102/488490-20210208155507407-1040650420.png) 1. api 模組相當於 gateway, 接收和響應請求,還包括鑑權, 引數的校驗和組裝,呼叫 command, query 的介面。 2. common 模組封裝一些和業務無關的通用功能類。 3. query 是讀模組,封裝非實時的查詢介面,查詢"從資料庫"。 4. command 是寫模組,封裝領域的業務邏輯,操作"主資料庫"。 按照上圖,用 idea 建立專案結構如下 ![](https://img2020.cnblogs.com/blog/488490/202102/488490-20210208155543404-1252942376.png) 對 command 和 query 模組再進行細化 ![](https://img2020.cnblogs.com/blog/488490/202102/488490-20210208155620201-1986039308.png) 因為 command 模組我們使用領域驅動開發,所以拆分成服務(Service), 倉儲(Repository), ORM, 聚合根(Aggregate)。 Query 只是簡單的查詢,我們直接用 Dao 訪問資料庫,然後把資料轉成 DTO 返回。 根據上圖,再細化專案的文件結構 ![](https://img2020.cnblogs.com/blog/488490/202102/488490-20210208161622202-386373869.png) ### 2.2 配置檔案 假設我們有三個環境, 分別是開發(dev), 測試(uat), 生產(prod)。每個模組都有單獨的配置檔案。 api: application-api-dev.yml application-api-uat.yml application-api-prod.yml command: application-command-dev.yml application-command-uat.yml application-command-prod.yml query: application-query-dev.yml application-query-uat.yml application-query-prod.yml 在系統啟動時,指定使用的環境, api 作為啟動專案,新增 bootstrap.yml, 因為 bootstrap.yml 優先於 application.yml 生效,所以可以在 bootstrap.yml 配置啟動環境。 我們啟用 dev 環境, bootstrap.yml 內容如下: ```yml spring: profiles: active: common-dev,command-dev,query-dev,api-dev ``` 那麼,對應的 application-common-dev.yml, application-command-dev.yml, application-query-dev.yml, application-api-dev.yml 配置檔案將起效。 ### 2.3 執行 在 query 專案新增一個介面 ```java public interface UserQueryService { String getName(Long id); } ``` 並實現它 ```java @Service public class UserQueryServiceImpl implements UserQueryService { @Override public String getName(Long id) { return "my name is grissom" + id; } } ``` 在 api 中呼叫該介面 ```java @RestController @RequestMapping("user") public class UserController { private final UserQueryService userQueryService; public UserController(UserQueryService userQueryService) { this.userQueryService = userQueryService; } @GetMapping("/name/{id}") public String name(@PathVariable("id") Long id) { return this.userQueryService.getName(id); } } ``` 將 api 作為啟動項,配置 application-api-dev.yml, 開放 8003 埠 ```yml server: port: 8003 ``` 用 postman 請求 ![](https://img2020.cnblogs.com/blog/488490/202102/488490-20210208161710012-274639215.png) 至此,咱們的專案結構已經搭建好。 下一篇再寫如何訪問資料庫。 # 原始碼 [https://github.com/grissomlau/cqrs-springboot](https://github.com/grissomlau/cqrs-springboot)