999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于Spring Boot與MyBatis框架構建動態讀寫分離模型

2021-03-17 07:32:48張旭剛張昕高若寒
微型電腦應用 2021年2期
關鍵詞:設置數據庫方法

張旭剛, 張昕, 高若寒

(國電南瑞科技股份有限公司 信息系統集成分公司, 江蘇 南京 210000)

0 引言

讀寫分離集群,不僅提高了系統的健壯性和可靠性,以及系統的吞吐量和性能,保障了系統業務的連續性,而且也實現了資源的最大利用率。當前的實現方法主要通過靜態方式配置,主要有中間件方式,如amoeba和mysql-proxy,分業務方式,對讀寫操作配置url。靜態方式缺乏靈活性,無法根據系統負載、用戶需求等情況,實現資源的快速動態收縮,難以滿足在不停機的條件下進行數據源切換,無法保證業務的連續性。

利用Spring Boot和MyBatis框架提供的優勢,通過面向切面編程AOP,實現一種對應用透明、數據源可以動態收縮與切換的模型。

1 Spring Boot架構

Spring Boot是由Pivotal團隊提供,簡化Spring開發的微服務框架。通過約定優于配置和起步依賴,簡化復雜的依賴關系,大量減少XML配置文件,基本實現自動化位置,能夠快速創建獨立運行的Spring項目,并且集成了主流框架,如AOP和MyBatis。為實現動態讀寫分離模型,主要利用面向切面編程技術AOP、MyBatis映射、SpringBoot的類Abstract Routing Data Source和Thread Local實現不同線程間的數據隔離[1]。

1.1 Spring AOP

Spring AOP(Aspect-Oriented Programming,面向切面編程),是一種稱為“橫切”的技術,把與業務無關邏輯,但為業務模塊共同調用的邏輯或功能封裝起來,將其命名為“Aspect”,即方面,減少系統的重復代碼,降低模塊間的耦合度,便于后期的操作和維護。在論文中,主要使用AOP的前置通知,攔截MyBatis映射的SQL語句,動態選擇數據源。

1.2 MyBatis映射

Mybatis是一個支持普通SQL查詢、存儲過程和高級映射的優秀持久層框架,在持久層映射關系的開發中,可以不用寫實現類,能以代理方式自動生成實現代碼,同時SQL語句寫在映射XML文件中,實現了代碼與SQL分離,降低耦合度。在映射XML文件中,通過id標識不同類型的SQL語句,對查詢、插入、刪除和更新語句進行區分,如查詢語句的id前綴為query,刪除語句的id前綴為delete,通過甄別判斷為不同SQL語句選擇對應的數據源,實現動態的讀寫分離。

1.3 Abstract Routing Data Source

Spring Boot提供了Abstract Routing Data Source根據用戶定義的規則選擇當前的數據源,可以在執行SQL操作前,設置使用的數據源,實現動態路由數據源的模型,它的方法determine Target Data Source()返回一個數據源,在該方法內部會調用抽象方法determine Current Lookup Key()決定使用哪個數據源,lookup key鍵通常是通過Thread Local綁定的上下文來實現。

1.4 Thread Local

Thread Local作用是提供線程內的局部變量,維護變量時Thread Local為每個使用該變量的線程提供獨立的變量副本。

在面向切面編程AOP的前置通知中通過Thread Local設置線程的數據源類型,是讀數據源還是寫數據源。在返回數據源的時候,通過determine Current Lookup Key()調用Thread Local取得線程的數據源類型,從而為本次訪問指定具體的數據源,是訪問讀庫還是寫庫[2]。

2 動態讀寫分離設計與實現

2.1 總體架構

程序實現基于Spring Boot框架,通過Maven進行編譯、測試和打包。Spring Boot基于Spring,減少了配置,簡化了編碼,使開發更高效便捷[3]。整體實現分五層,第一層客戶端即應用程序,發起數據訪問;第二層訪問到DAO(數據訪問對象),訪問的sql語句配置在MyBatis的映射文件里,與程序的DAO接口形成映射關系,由MyBatis自動實現接口的文件,對數據庫進行訪問;第三層,AOP,即面向切面編程層,在DAO訪問數據庫之前,進行攔截,根據訪問id進行動態選擇數據源,如果是查詢語句則訪問讀庫,如果是修改語句,則指向到主數據庫,實現數據的讀寫分離,主要功能有負載均衡、高可用性、SQL過濾、讀寫分離和數據庫路由等;第四層,創建和封裝兩個數據源,每個數據源創建一個數據庫資源池,分別指向寫數據庫和讀數據庫;第五層,主備數據庫之間,通過binlog進行數據實時同步,并進行故障切換[4]。

通過上面五層,與Spring Boot和MyBatis架構構建程序一致,對原有程序透明,無任何侵入,原程序不需要任何改造,簡單便捷地實現了動態的數據庫讀寫分離[5]。

同時,這種結構可以進行橫向擴展,當性能無法滿足需求時,添加數據源,添加數據庫,進行負載分擔,對應用透明,如圖1所示。

2.2 讀寫分離的實現

實現MySQL數據庫的動態讀寫分離,讀寫分離的實現類圖,如圖2所示。

主要由四個類實現,Dynamic Data Source動態的根據數據源的值返回數據源;Data Source Context Holder封裝了Thread Local,用于設置和獲取本次訪問的數據源的值;Dynamic Data Source Aspect實現AOP的前置通知,攔截和解析SQL的id,根據id判斷是讀操作還是寫操作,通過Data Source Context Holder動態設置數據源的值,然后Dynamic Data Source獲取到要訪問的數據源;Multi Data Source Con-fig配置多個數據源,在應用啟動后有多個數據源可以選擇。

圖1 總體結構圖

圖2 讀寫分離的實現類圖

Dynamic Data Source,用于獲取數據庫訪問的數據源,如果是查詢操作,返回只讀庫數據源,如果是增刪改則訪問寫庫。繼承Abstract Routing Data Source并重寫其中的方法determine Current Lookup Key(),該方法調用封裝了Thread Local的Database Context Holder,獲取當前線程的Database Type。

Data Source Context Holder,用戶設置數據庫訪問的數據源,具體設置通過切面攔截調用該類的方法set Data Source Type。該類擁有一個Thread Local的靜態常量私有屬性private static final Thread Local〈String〉 CONTEXT_HOLDER = new Thread Local〈String〉(),靜態方法set Data Source Type(String data Source Key)和get Data Source Type()通過CONTEXT_HOLDER屬性,用于標識數據源,給每個訪問數據庫的線程返回要訪問的數據源。

Dynamic Data Source Aspect用于定義要攔截的SQL操作,通過前置通知解析MyBatis中配置的id,根據id判斷SQL操作是讀操作還是增刪改,并利用Data Source Context Holder的靜態方法設置當前線程的數據源類型。在進行數據源選擇時,Dynamic Data Source返回設置的當前線程的數據源類型,當前線程準確地找到需要訪問的數據源。它的主要實現方法如下。

@Pointcut("execution( * com.sboot.dao.*.*(..))")

public void daoAspect() {

}

@Before("daoAspect()")

public void switchDataSource(JoinPoint point) {

System.out.println("Begin to execute "+point.getSignature().getName());

Boolean isQueryMethod = isQueryMethod(point.getSignature().getName());

if (isQueryMethod) {

DataSourceContextHolder.setDataSourceType("slave");

System.out.println("Slave DataSource begin to execute "+point.getSignature().getName());

}

}

Multi Data Source Config,是一個基于注解的配置,主要封裝了寫和讀兩個數據源,實現多數據源,需要取消Spring Boot的自動數據源配置,主要實現方法如下。

@Bean("dynamicDataSource")

public DataSource dynamicDataSource() {

Map〈Object, Object〉 targetDataSources = new HashMap〈Object, Object〉();

targetDataSources.put("master", masterDataSource());

targetDataSources.put("slave", slaveDataSource());

DynamicDataSource dataSource = new DynamicDataSource();

dataSource.setTargetDataSources(targetDataSources);

dataSource.setDefaultTargetDataSource(masterDataSource());

return dataSource;

}

2.3 配置多數據源

在application.yml中添加兩個數據源[6]:

pring:

datasource:

master://寫數據源的配置

url:

jdbc:mysql://192.168.10.12:3306/masterdb?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true

username: studba

password: stuDba1

driverClassName: com.mysql.cj.jdbc.Driver

slave://讀數據源的配置

url:

jdbc:mysql://192.168.10.13:3306/slavedb?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true

username: studba

password: stuDba1

driverClassName: com.mysql.cj.jdbc.Driver

然后在類DataSourceConfig中,利用注解的方式生成數據源:

@Primary

@Bean("masterDataSource")

@ConfigurationProperties(prefix = "spring.datasource.master")

public DataSource masterDataSource() {

return DataSourceBuilder.create().build();

}

通過@ConfigurationProperties注解把在配置文件的配置自動的匹配配置數據源需要的值,生成數據源。備數據源的原理與上面一致。

2.4 數據訪問流程

數據訪問流程,如圖3所示。

圖3 數據訪問流程

(1) 客戶端訪問數據庫,正常流程走到DAO層,MyBatis進行映射接口,取得映射的sql語句,如findStudentById。

(2) 取得sql語句訪問數據庫。

(3) 通過@Before("daoAspect()")攔截訪問,并檢查是查詢語句,設置數據源為讀數據庫。

判斷出是find開頭的sql語句,設置讀數據源DataSourceContextHolder.setDataSourceType("slave")。

(4) MultiDynamicDataSource

在方法determineCurrentLookupKey()中返回數據源類型return DataSourceContextHolder.getDataSourceType()。

(5) MultiDynamicDataSource的方法

determineTargetDataSource()根據上面determineCurrentLookupKey()函數返回的key值選擇一個指定的數據源。

(6) 返回要訪問的數據源,本次訪問返回的是讀數據源。

(7) 根據返回的讀數據源,訪問讀數據庫。

2.5 應用驗證

通過學生ID查詢學生信息進行驗證,查詢操作到讀庫進行操作。查詢學生信息的MyBatis SQL id是findStudent ById,在瀏覽器輸入http://192.168.1.10:8080/stuInfo,進行查詢,日志輸出信息,如圖4所示。

圖4 測試驗證

日志打印出執行sql語句findStudentById,動態選擇讀數據源Slave DataSource執行。

3 總結

本文基于Spring Boot和MyBatis框架,實現了動態的MySQL讀寫分離模型,方法簡單、便捷,對應用透明,低耦合,無侵入性,安裝和拆卸對現有程序無任何影響,沒有額外的成本。后續可加入多數據源,通過zookeeper進行狀態監控和管理,實現更智能和動態的數據庫的橫向擴展和收縮,滿足云計算場景需求。

猜你喜歡
設置數據庫方法
中隊崗位該如何設置
少先隊活動(2021年4期)2021-07-23 01:46:22
數據庫
財經(2017年2期)2017-03-10 14:35:35
數據庫
財經(2016年15期)2016-06-03 07:38:02
用對方法才能瘦
Coco薇(2016年2期)2016-03-22 02:42:52
數據庫
財經(2016年3期)2016-03-07 07:44:46
數據庫
財經(2016年6期)2016-02-24 07:41:51
本刊欄目設置說明
中俄臨床醫學專業課程設置的比較與思考
四大方法 教你不再“坐以待病”!
Coco薇(2015年1期)2015-08-13 02:47:34
捕魚
主站蜘蛛池模板: aaa国产一级毛片| 一级毛片免费播放视频| 国产精品流白浆在线观看| 99热这里只有精品免费| 欧美激情伊人| 日韩高清成人| 久久久久青草线综合超碰| 久久久久久午夜精品| 中文字幕乱码二三区免费| 欧美精品黑人粗大| 国内精品久久久久久久久久影视| 久久久久青草线综合超碰| 午夜性爽视频男人的天堂| 色欲色欲久久综合网| 国产毛片高清一级国语| 国产女人爽到高潮的免费视频| 日韩经典精品无码一区二区| 亚洲天堂2014| 欧美 亚洲 日韩 国产| 99人妻碰碰碰久久久久禁片| 免费国产小视频在线观看| 久久成人免费| 日本一区二区三区精品国产| 99er这里只有精品| 国产粉嫩粉嫩的18在线播放91| 国产欧美日韩va另类在线播放 | 久久精品中文字幕少妇| 99无码熟妇丰满人妻啪啪| a级毛片免费在线观看| 国产午夜一级毛片| 黄片在线永久| 波多野结衣久久高清免费| 免费人成视网站在线不卡| 欧美a网站| 国产日韩av在线播放| 久996视频精品免费观看| 国产成人精品一区二区三区| 91蝌蚪视频在线观看| 91成人免费观看在线观看| 国产尤物在线播放| 欧美午夜在线观看| 日韩高清成人| 亚洲,国产,日韩,综合一区| 大香伊人久久| 欧美日本在线播放| 欧美日韩免费观看| 人妻精品久久无码区| 亚洲乱伦视频| 精品国产美女福到在线直播| 国产精品任我爽爆在线播放6080| 国产精品亚洲天堂| 超碰精品无码一区二区| 亚洲成在人线av品善网好看| 国产黄网永久免费| 亚洲成人网在线观看| 久久五月天国产自| 天天综合网在线| 夜精品a一区二区三区| 日韩成人在线视频| 亚洲最新在线| 无码'专区第一页| 伊在人亚洲香蕉精品播放| 色哟哟国产成人精品| jizz国产视频| 嫩草国产在线| 日韩福利视频导航| 99这里只有精品免费视频| 欧美在线中文字幕| 国产第一页免费浮力影院| 欧美日本在线| 国产精品永久在线| 日韩毛片免费观看| 亚洲一区无码在线| 一本大道视频精品人妻| 黑人巨大精品欧美一区二区区| 97成人在线视频| 国国产a国产片免费麻豆| 精品视频一区二区三区在线播| 欧美人与牲动交a欧美精品| 国产拍揄自揄精品视频网站| 国产亚洲高清在线精品99| 亚洲成人网在线播放|