国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot 項(xiàng)目優(yōu)雅實(shí)現(xiàn)讀寫分離

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot 項(xiàng)目優(yōu)雅實(shí)現(xiàn)讀寫分離。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、讀寫分離介紹

當(dāng)使用Spring Boot開發(fā)數(shù)據(jù)庫應(yīng)用時(shí),讀寫分離是一種常見的優(yōu)化策略。讀寫分離將讀操作和寫操作分別分配給不同的數(shù)據(jù)庫實(shí)例,以提高系統(tǒng)的吞吐量和性能。

讀寫分離實(shí)現(xiàn)主要是通過動(dòng)態(tài)數(shù)據(jù)源功能實(shí)現(xiàn)的,動(dòng)態(tài)數(shù)據(jù)源是一種通過在運(yùn)行時(shí)動(dòng)態(tài)切換數(shù)據(jù)庫連接的機(jī)制。它允許應(yīng)用程序根據(jù)不同的條件或配置選擇不同的數(shù)據(jù)源,以實(shí)現(xiàn)更靈活和可擴(kuò)展的數(shù)據(jù)庫訪問。

二、實(shí)現(xiàn)讀寫分離-基礎(chǔ)

1. 配置主數(shù)據(jù)庫和從數(shù)據(jù)庫的連接信息

# 主庫配置
spring.datasource.master.jdbc-url=jdbc:mysql://ip:port/master?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.master.username=master
spring.datasource.master.password=123456
spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver

# 從庫配置
spring.datasource.slave.jdbc-url=jdbc:mysql://ip:port/slave?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.slave.username=slave
spring.datasource.slave.password=123456
spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver 

2. 創(chuàng)建主數(shù)據(jù)庫和從數(shù)據(jù)庫的數(shù)據(jù)源配置類

通過不同的條件限制和配置文件前綴可以完成不同數(shù)據(jù)源的創(chuàng)建工作,不止是主從也可以是多個(gè)不同的數(shù)據(jù)庫

主庫數(shù)據(jù)源配置

@Configuration
@ConditionalOnProperty("spring.datasource.master.jdbc-url")
public class MasterDataSourceConfiguration {
    @Bean("masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }
}

從庫數(shù)據(jù)源配置

@Configuration
@ConditionalOnProperty("spring.datasource.slave.jdbc-url")
public class SlaveDataSourceConfiguration {
    @Bean("slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }
}



3. 創(chuàng)建主從數(shù)據(jù)源枚舉

public enum DataSourceTypeEnum {
    /**
     * 主庫
     */
    MASTER,

    /**
     * 從庫
     */
    SLAVE,
   ;
  
}

4. 創(chuàng)建動(dòng)態(tài)路由數(shù)據(jù)源

這兒做了一個(gè)開關(guān),可以控制讀寫分離的開啟和關(guān)閉工作,可以講操作全部切換到主庫進(jìn)行。然后根據(jù)上下文中的數(shù)據(jù)源類型來返回不同的數(shù)據(jù)源類型枚舉

@Slf4j
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    @Value("${DB_RW_SEPARATE_SWITCH:false}")
    private boolean dbRwSeparateSwitch;
    @Override
    protected Object determineCurrentLookupKey() {
        if(dbRwSeparateSwitch && DataSourceTypeEnum.SLAVE.equals(DataSourceContextHolder.getDataSourceType())) {
            log.info("DynamicRoutingDataSource 切換數(shù)據(jù)源到從庫");
            return DataSourceTypeEnum.SLAVE;
        }
        log.info("DynamicRoutingDataSource 切換數(shù)據(jù)源到主庫");
        // 根據(jù)需要指定當(dāng)前使用的數(shù)據(jù)源,這里可以使用ThreadLocal或其他方式來決定使用主庫還是從庫
        return DataSourceTypeEnum.MASTER;
    }
}

5. 創(chuàng)建動(dòng)態(tài)數(shù)據(jù)源配置類

將主數(shù)據(jù)庫和從數(shù)據(jù)庫的數(shù)據(jù)源添加到動(dòng)態(tài)數(shù)據(jù)源中,并可以通過枚舉創(chuàng)建一個(gè)數(shù)據(jù)源 map,這樣就可以通過上面的路由返回的枚舉來切換數(shù)據(jù)源

@Configuration
@ConditionalOnProperty("spring.datasource.master.jdbc-url")
public class DynamicDataSourceConfiguration {
    @Bean("dataSource")
    @Primary
    public DataSource dynamicDataSource(DataSource masterDataSource, DataSource slaveDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceTypeEnum.MASTER, masterDataSource);
        targetDataSources.put(DataSourceTypeEnum.SLAVE, slaveDataSource);

        DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource);
        return dynamicDataSource;
    }
}

6. 創(chuàng)建DatasourceContextHolder類使用ThreadLocal存儲(chǔ)當(dāng)前線程的數(shù)據(jù)源類型

注意這兒有個(gè)潛在風(fēng)險(xiǎn)就是創(chuàng)建新的線程時(shí)會(huì)導(dǎo)致 ThreadLocal 中的數(shù)據(jù)無法正確讀取,如果涉及到在開啟新線程可以使用 TransmittableThreadLocal 來進(jìn)行父子線程數(shù)據(jù)的同步,git 地址: https://github.com/alibaba/transmittable-thread-local

public class DataSourceContextHolder {
    private static final ThreadLocal<DataSourceTypeEnum> contextHolder = new ThreadLocal<>();

    public static void setDataSourceType(DataSourceTypeEnum dataSourceType) {
        contextHolder.set(dataSourceType);
    }

    public static DataSourceTypeEnum getDataSourceType() {
        return contextHolder.get();
    }

    public static void clearDataSourceType() {
        contextHolder.remove();
    }
}

7. 創(chuàng)建自定義注解,用于標(biāo)記主和從數(shù)據(jù)源

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MasterDataSource {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SlaveDataSource {
}

8. 創(chuàng)建切面類,攔截?cái)?shù)據(jù)庫操作,并根據(jù)注解設(shè)置切換數(shù)據(jù)源參數(shù)

@Aspect
@Component
public class DataSourceAspect {

    @Before("@annotation(xxx.MasterDataSource)")
    public void setMasterDataSource(JoinPoint joinPoint) {
        DataSourceContextHolder.setDataSourceType(DataSourceTypeEnum.MASTER);
    }

    @Before("@annotation(xxx.SlaveDataSource)")
    public void setSlaveDataSource(JoinPoint joinPoint) {
        DataSourceContextHolder.setDataSourceType(DataSourceTypeEnum.SLAVE);
    }

    @After("@annotation(xxx.MasterDataSource) || @annotation(xxx.SlaveDataSource)")
    public void clearDataSource(JoinPoint joinPoint) {
        DataSourceContextHolder.clearDataSourceType();
    }
}

9. 在Service層的方法上使用自定義注解標(biāo)記查詢數(shù)據(jù)源

@Service
public class TestService {
    @Autowired
    private TestDao testDao;

    @SlaveDataSource
    public Test test() {
        return testDao.queryByPrimaryKey(11L);
    }
}

10. 排除掉數(shù)據(jù)源自動(dòng)配置類

如果不排除自動(dòng)配置類會(huì)導(dǎo)致初始化多個(gè) dataSource 對(duì)象導(dǎo)致出現(xiàn)問題

SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

三、實(shí)現(xiàn)讀寫分離-進(jìn)階

1. 使用鏈接池,以Hikari為例

修改鏈接配置,加入鏈接池相關(guān)配置即可

# 主庫配置
spring.datasource.master.jdbc-url=jdbc:mysql://ip:port/master?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.master.username=master
spring.datasource.master.password=123456
spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.master.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.master.hikari.name=master
spring.datasource.master.hikari.minimum-idle=5
spring.datasource.master.hikari.idle-timeout=30
spring.datasource.master.hikari.maximum-pool-size=10
spring.datasource.master.hikari.auto-commit=true
spring.datasource.master.hikari.pool-name=DatebookHikariCP
spring.datasource.master.hikari.max-lifetime=1800000
spring.datasource.master.hikari.connection-timeout=30000
spring.datasource.master.hikari.connection-test-query=SELECT 1

# 從庫配置
spring.datasource.slave.jdbc-url=jdbc:mysql://ip:port/slave?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.slave.username=root
spring.datasource.slave.password=123456
spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.slave.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.slave.hikari.name=master
spring.datasource.slave.hikari.minimum-idle=5
spring.datasource.slave.hikari.idle-timeout=30
spring.datasource.slave.hikari.maximum-pool-size=10
spring.datasource.slave.hikari.auto-commit=true
spring.datasource.slave.hikari.pool-name=DatebookHikariCP
spring.datasource.slave.hikari.max-lifetime=1800000
spring.datasource.slave.hikari.connection-timeout=30000
spring.datasource.slave.hikari.connection-test-query=SELECT 1

2. 集成 mybatis 并在寫入時(shí)強(qiáng)制切換到主庫

不需要做任何配置,正常集成 mybatis 即可使用讀寫分離功能

可以通過 mybatis 的攔截器在寫入操作時(shí)強(qiáng)制切換到主庫

@Intercepts({
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
})
@Component
public class WriteInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 獲取 SQL 類型
        DataSourceTypeEnum dataSourceType = DataSourceContextHolder.getDataSourceType();
        if(DataSourceTypeEnum.SLAVE.equals(dataSourceType)) {
            DataSourceContextHolder.setDataSourceType(DataSourceTypeEnum.MASTER);
        }
        try {
            // 執(zhí)行 SQL
            return invocation.proceed();
        } finally {
            // 恢復(fù)數(shù)據(jù)源  考慮到寫入后可能會(huì)反查,后續(xù)都走主庫
            // DataSourceContextHolder.setDataSourceType(dataSourceType);
        }
    }
}

作者:京東健康?蘇曼

來源:京東云開發(fā)者社區(qū) 轉(zhuǎn)發(fā)請(qǐng)注明來源文章來源地址http://www.zghlxwxcb.cn/news/detail-746090.html

到了這里,關(guān)于SpringBoot 項(xiàng)目優(yōu)雅實(shí)現(xiàn)讀寫分離的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 一、Sharding-JDBC系列01:整合SpringBoot實(shí)現(xiàn)分庫分表,讀寫分離

    一、Sharding-JDBC系列01:整合SpringBoot實(shí)現(xiàn)分庫分表,讀寫分離

    目錄 一、概述 二、案例演示-水平分表 (1)、創(chuàng)建springboot工程 (2)、創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)表 (3)、application.yaml配置分片規(guī)則?? (4)、測試數(shù)據(jù)插入、查詢操作 4.1、插入-控制臺(tái)SQL日志? 4.2、查詢-控制臺(tái)SQL日志 ?三、案例演示-水平分庫 (1)、創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)表? (2)、application.yaml配置

    2024年02月02日
    瀏覽(17)
  • SpringBoot項(xiàng)目如何優(yōu)雅的實(shí)現(xiàn)操作日志記錄

    SpringBoot項(xiàng)目如何優(yōu)雅的實(shí)現(xiàn)操作日志記錄

    在實(shí)際開發(fā)當(dāng)中,對(duì)于某些關(guān)鍵業(yè)務(wù),我們通常需要記錄該操作的內(nèi)容,一個(gè)操作調(diào)一次記錄方法,每次還得去收集參數(shù)等等,會(huì)造成大量代碼重復(fù)。 我們希望代碼中只有業(yè)務(wù)相關(guān)的操作,在項(xiàng)目中使用注解來完成此項(xiàng)功能。 通常就是使用Spring中的AOP特性來實(shí)現(xiàn)的,那么在

    2024年01月18日
    瀏覽(24)
  • java項(xiàng)目實(shí)現(xiàn)讀寫分離,項(xiàng)目連接Linux部署的數(shù)據(jù)庫異常javax.net.ssl.SSLHandshakeException: No appropriate protocol

    java項(xiàng)目實(shí)現(xiàn)讀寫分離,項(xiàng)目連接Linux部署的數(shù)據(jù)庫異常javax.net.ssl.SSLHandshakeException: No appropriate protocol

    1、對(duì)項(xiàng)目進(jìn)行優(yōu)化實(shí)現(xiàn)讀寫分離,項(xiàng)目啟動(dòng)時(shí)報(bào)錯(cuò)如下: Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) 原因:javax.net.ssl.SSLHandshakeException:沒有適當(dāng)?shù)膮f(xié)議(協(xié)議被禁用或密碼套件不合適) 2、bug解決: ? ? 注意: useSSL=f

    2024年02月04日
    瀏覽(23)
  • SpringBoot_第七章(讀寫分離)

    SpringBoot_第七章(讀寫分離)

    目錄 1:MybatisPlus(讀寫分離) 1.1:首先創(chuàng)建三個(gè)數(shù)據(jù)庫1主2從 1.2:代碼實(shí)例 1.3:優(yōu)缺點(diǎn)分析 2:SpringBoot路由數(shù)據(jù)源(讀寫分離) 2.1:實(shí)現(xiàn)原理 2.2:代碼實(shí)現(xiàn) 2.3:測試代碼? 2.4:優(yōu)缺點(diǎn)分析 這里列舉了兩種讀寫分離實(shí)現(xiàn)方案,如下 表名是user表 1:導(dǎo)入pom 2:配置spring的主從

    2024年02月06日
    瀏覽(18)
  • Vue加SpringBoot實(shí)現(xiàn)項(xiàng)目前后端分離

    Vue加SpringBoot實(shí)現(xiàn)項(xiàng)目前后端分離

    首先需要搭建一個(gè)Vue的腳手架項(xiàng)目(已經(jīng)放在gitee里面了,下面是gitee網(wǎng)址,可以直接拉) (vue-web: 這個(gè)是Vue項(xiàng)目模板,沒有后臺(tái)數(shù)據(jù)) 那么接下來就是實(shí)現(xiàn)前后端分離的步驟 首先我們需要有一個(gè)登錄頁面 登錄的點(diǎn)擊事件利用axios提交到后臺(tái)去,代碼放在后面(沒有樣式也可以

    2024年02月06日
    瀏覽(29)
  • 【云原生】前后端分離項(xiàng)目下 如何優(yōu)雅的聯(lián)調(diào)程序?

    【云原生】前后端分離項(xiàng)目下 如何優(yōu)雅的聯(lián)調(diào)程序?

    Apifox 是 API 文檔、API 調(diào)試、API Mock、API 自動(dòng)化測試一體化協(xié)作平臺(tái),定位 Postman + Swagger + Mock + JMeter 。通過一套系統(tǒng)、一份數(shù)據(jù),解決多個(gè)系統(tǒng)之間的數(shù)據(jù)同步問題。只要定義好 API 文檔,API 調(diào)試、API 數(shù)據(jù) Mock、API 自動(dòng)化測試就可以直接使用,無需再次定義;API 文檔和 API

    2023年04月09日
    瀏覽(22)
  • SpringBoot + K8S 中的滾動(dòng)發(fā)布、優(yōu)雅停機(jī)、彈性伸縮、應(yīng)用監(jiān)控、配置分離

    前言 配置 健康檢查 滾動(dòng)更新 彈性伸縮 Prometheus集成 配置分離 匯總配置 業(yè)務(wù)層面 運(yùn)維層面 K8s + SpringBoot實(shí)現(xiàn)零宕機(jī)發(fā)布:健康檢查+滾動(dòng)更新+優(yōu)雅停機(jī)+彈性伸縮+Prometheus監(jiān)控+配置分離(鏡像復(fù)用) 基于 Spring Boot + MyBatis Plus + Vue Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持

    2024年02月07日
    瀏覽(19)
  • SpringBoot + Vue前后端分離項(xiàng)目實(shí)戰(zhàn) || 四:用戶管理功能實(shí)現(xiàn)

    SpringBoot + Vue前后端分離項(xiàng)目實(shí)戰(zhàn) || 四:用戶管理功能實(shí)現(xiàn)

    系列文章: SpringBoot + Vue前后端分離項(xiàng)目實(shí)戰(zhàn) || 一:Vue前端設(shè)計(jì) SpringBoot + Vue前后端分離項(xiàng)目實(shí)戰(zhàn) || 二:Spring Boot后端與數(shù)據(jù)庫連接 SpringBoot + Vue前后端分離項(xiàng)目實(shí)戰(zhàn) || 三:Spring Boot后端與Vue前端連接 SpringBoot + Vue前后端分離項(xiàng)目實(shí)戰(zhàn) || 四:用戶管理功能實(shí)現(xiàn) SpringBoot + Vue前后

    2024年02月11日
    瀏覽(38)
  • 項(xiàng)目練習(xí):構(gòu)建讀寫分離的數(shù)據(jù)庫集群

    目錄 一、目標(biāo)實(shí)現(xiàn) 二、項(xiàng)目準(zhǔn)備 三、項(xiàng)目實(shí)施 1.配置基礎(chǔ)環(huán)境 1.1修改主機(jī)名 1.2配置3臺(tái)群集虛擬機(jī)的/etc/hosts文件 1.3.配置網(wǎng)卡 1.4.配置本地yum源 2.部署Mycat中間件服務(wù) 2.1安裝KDJ環(huán)境 3.部署MariaDB主從數(shù)據(jù)庫集群服務(wù) 3.1安裝MariaDB服務(wù) 3.2初始化MariaDB數(shù)據(jù)庫 3.3配置數(shù)據(jù)庫集群主

    2024年02月02日
    瀏覽(25)
  • 搭建redis主從,哨兵配置,集成到springboot中配置讀寫分離

    搭建redis主從,哨兵配置,集成到springboot中配置讀寫分離

    文章介紹Ubuntu系統(tǒng)搭建redis,并完成主從的讀寫分離配置,為主節(jié)點(diǎn)搭建三臺(tái)哨兵服務(wù),并集成到springboot中。 本篇文章是通過其他優(yōu)秀博文學(xué)習(xí)后,用作學(xué)習(xí)記錄使用。 大佬博客: https://blog.csdn.net/Wei_Naijia/article/details/125704197 https://blog.csdn.net/lssqk/article/details/127220990 1.Ubunt

    2024年02月09日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包