Spring Boot項(xiàng)目中結(jié)合MyBatis實(shí)現(xiàn)MySQL的自動(dòng)主從切換功能
原理解析
1. MySQL主從復(fù)制(Master-Slave Replication)
- 工作原理:MySQL主從復(fù)制通過(guò)二進(jìn)制日志(binary log)來(lái)同步數(shù)據(jù)。主服務(wù)器記錄所有更改操作到二進(jìn)制日志中,從服務(wù)器讀取這些日志并執(zhí)行相應(yīng)的SQL語(yǔ)句來(lái)保持與主服務(wù)器的數(shù)據(jù)一致。
- 延遲問(wèn)題:由于網(wǎng)絡(luò)傳輸和處理時(shí)間,從庫(kù)可能會(huì)有短暫的數(shù)據(jù)滯后,這對(duì)于需要實(shí)時(shí)一致性的場(chǎng)景是一個(gè)挑戰(zhàn)。
2. 讀寫(xiě)分離
- 目的:提高系統(tǒng)性能和可用性。通過(guò)將讀請(qǐng)求分配給從庫(kù),寫(xiě)請(qǐng)求發(fā)送給主庫(kù),可以減少主庫(kù)的壓力,提升系統(tǒng)的整體性能。
- 實(shí)現(xiàn)方式:可以通過(guò)數(shù)據(jù)庫(kù)中間件或框架層面的配置來(lái)實(shí)現(xiàn)。在這個(gè)例子中,我們使用Apache ShardingSphere來(lái)實(shí)現(xiàn)讀寫(xiě)分離。
3. 自動(dòng)故障轉(zhuǎn)移
- 原理:當(dāng)檢測(cè)到主庫(kù)不可用時(shí),系統(tǒng)會(huì)自動(dòng)選擇一個(gè)從庫(kù)作為新的主庫(kù),并重新調(diào)整讀寫(xiě)分配。這通常涉及到心跳檢測(cè)、狀態(tài)監(jiān)控等機(jī)制。
- 工具支持:除了ShardingSphere外,還可以使用MHA(MySQL Master High Availability)或其他高可用解決方案。
實(shí)現(xiàn)步驟詳解
1. 引入依賴
在pom.xml
中添加必要的依賴,包括Spring Boot Starter、MyBatis Starter以及ShardingSphere:
深色版本
<dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- MyBatis Starter --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <!-- ShardingSphere for read-write splitting --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.1.1</version> </dependency> </dependencies>
2. 配置數(shù)據(jù)源
編輯application.yml
文件以配置多個(gè)數(shù)據(jù)源,并設(shè)置ShardingSphere規(guī)則以實(shí)現(xiàn)讀寫(xiě)分離:
深色版本
spring: shardingsphere: datasource: names: master,slave0,slave1 master: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://master_host:3306/your_db?useSSL=false&serverTimezone=UTC username: your_username password: your_password slave0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://slave0_host:3306/your_db?useSSL=false&serverTimezone=UTC username: your_username password: your_password slave1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://slave1_host:3306/your_db?useSSL=false&serverTimezone=UTC username: your_username password: your_password masterslave: load-balance-algorithm-type: round_robin # 負(fù)載均衡策略 name: ms_ds # 數(shù)據(jù)源名稱 master-data-source-name: master # 主庫(kù)數(shù)據(jù)源名稱 slave-data-source-names: slave0,slave1 # 從庫(kù)數(shù)據(jù)源名稱列表 props: sql: show: true # 是否顯示SQL語(yǔ)句
3. 配置MyBatis
創(chuàng)建MyBatis Mapper接口,并使用注解或XML配置SQL語(yǔ)句。這里以注解方式為例:
深色版本
package com.example.demo.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.util.List; import java.util.Map; @Mapper public interface UserMapper { /** * 查詢所有用戶信息. * 注意:對(duì)于查詢操作,ShardingSphere會(huì)選擇其中一個(gè)從庫(kù)來(lái)執(zhí)行查詢。 * * @return 用戶信息列表 */ @Select("SELECT * FROM users") List<Map<String, Object>> findAllUsers(); /** * 更新用戶信息. * 注意:寫(xiě)操作只會(huì)針對(duì)主庫(kù)執(zhí)行。 * * @param id 用戶ID * @param newName 新用戶名 */ void updateUserById(@Param("id") Long id, @Param("newName") String newName); }
確保你的Spring Boot應(yīng)用掃描到Mapper接口??梢栽谥黝惿咸砑?code>@MapperScan注解:
深色版本
package com.example.demo; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.example.demo.mapper") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
4. 使用Mapper進(jìn)行數(shù)據(jù)庫(kù)操作
現(xiàn)在你可以在Service層中注入并使用Mapper接口來(lái)進(jìn)行數(shù)據(jù)庫(kù)操作:
深色版本
package com.example.demo.service; import com.example.demo.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @Service public class UserService { @Autowired private UserMapper userMapper; /** * 獲取所有用戶信息. * * @return 用戶信息列表 */ public List<Map<String, Object>> getAllUsers() { return userMapper.findAllUsers(); } /** * 更新用戶名稱. * * @param id 用戶ID * @param newName 新用戶名 */ public void updateUserName(Long id, String newName) { userMapper.updateUserById(id, newName); } }
注意事項(xiàng)及最佳實(shí)踐
- 事務(wù)管理:確保所有寫(xiě)操作都在同一個(gè)事務(wù)中執(zhí)行,并且只對(duì)主庫(kù)進(jìn)行寫(xiě)操作??梢允褂?code>@Transactional注解來(lái)管理事務(wù)。
- 數(shù)據(jù)一致性:考慮到主從復(fù)制延遲的問(wèn)題,在某些場(chǎng)景下(如剛完成寫(xiě)操作后立即讀?。赡苄枰苯硬樵冎鲙?kù)以保證數(shù)據(jù)一致性。
- 健康檢查:建議定期監(jiān)控主從狀態(tài),確保從庫(kù)同步正常以及主庫(kù)可訪問(wèn)??梢酝ㄟ^(guò)定時(shí)任務(wù)或者外部工具來(lái)實(shí)現(xiàn)。
- 性能優(yōu)化:根據(jù)實(shí)際業(yè)務(wù)需求調(diào)整負(fù)載均衡策略,例如采用權(quán)重輪詢或其他高級(jí)算法來(lái)優(yōu)化查詢效率。
到此這篇關(guān)于Spring Boot項(xiàng)目中結(jié)合MyBatis實(shí)現(xiàn)MySQL的自動(dòng)主從切換的文章就介紹到這了,更多相關(guān)Spring Boot MyBatis自動(dòng)主從切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)之復(fù)雜度篇
算法復(fù)雜度分為時(shí)間復(fù)雜度和空間復(fù)雜度。其作用:?時(shí)間復(fù)雜度是度量算法執(zhí)行的時(shí)間長(zhǎng)短;而空間復(fù)雜度是度量算法所需存儲(chǔ)空間的大小2022-01-01Java導(dǎo)出網(wǎng)頁(yè)表格Excel過(guò)程詳解
這篇文章主要介紹了Java導(dǎo)出網(wǎng)頁(yè)表格Excel過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07SpringBoot?將配置文件掛到?jar?包外面的操作方法
在 SpringBoot 中,可以將配置文件放在 jar 包外面,這樣可以方便地修改配置而不需要重新打包和部署,這篇文章主要介紹了SpringBoot?如何將配置文件掛到?jar?包外面,需要的朋友可以參考下2023-03-03Java多線程之scheduledThreadPool的方法解析
這篇文章主要介紹了Java多線程之scheduledThreadPool的方法解析,queue是DelayedWorkQueue,但通過(guò)后面的分析可以知道,最大線程數(shù)是不起作用的,最多會(huì)起核心線程數(shù)的數(shù)量,需要的朋友可以參考下2023-12-12基于Spring AMQP實(shí)現(xiàn)消息隊(duì)列的示例代碼
Spring AMQP作為Spring框架的一部分,是一套用于支持高級(jí)消息隊(duì)列協(xié)議(AMQP)的工具,AMQP是一種強(qiáng)大的消息協(xié)議,旨在支持可靠的消息傳遞,本文給大家介紹了如何基于Spring AMQP實(shí)現(xiàn)消息隊(duì)列,需要的朋友可以參考下2024-03-03微服務(wù)中使用Maven BOM來(lái)管理你的版本依賴詳解
這篇文章主要介紹了微服務(wù)中使用Maven BOM來(lái)管理你的版本依賴,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12在Java中將jsonObject轉(zhuǎn)換成對(duì)象的實(shí)現(xiàn)方法
在現(xiàn)代的Web開(kāi)發(fā)中,JSON作為一種輕量級(jí)的數(shù)據(jù)交換格式,因其易讀性和易于解析的特點(diǎn)而被廣泛使用,本文將介紹如何在Java中將??jsonObject??轉(zhuǎn)換成Java對(duì)象,主要通過(guò)使用Gson庫(kù)來(lái)實(shí)現(xiàn)這一功能,需要的朋友可以參考下2025-04-04