1. 程式人生 > 其它 >SpringBoot-整合-MyCat-實現讀寫分離,mongodb視訊教程

SpringBoot-整合-MyCat-實現讀寫分離,mongodb視訊教程

+----------------------------------+--------+
4 rows in set (0.00 sec)


#### 修改表儲存引擎

如果是slave資料庫的表是MyISAM,master資料庫的表是InnoDB。直接覆蓋master資料庫來同步資料的話,slave資料庫表的儲存引擎也將會同步變成InnoDB。擴充套件:[InnoDB一棵B+樹可以存放多少行資料?](

)

#### 更換儲存引擎遇到的問題

`This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable)`

#### 出現的原因

在function裡面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支援。
如果我們開啟了 bin-log, 我們就必須為我們的function指定一個引數。

#### 解決方案

mysql>?set?global?log_bin_trust_function_creators=TRUE;


`Specified key was too long; max key length is 1000 bytes`

#### 出現的原因

1.  DB的 engine 是 MyISAM

2.  字符集是 utf8 ,1個 utf8=3bytes

3.  (索引長度總和) * 3 > 1000。

#### 解決方案

1.  修改DB engine 至 innodb

2.  更改字符集

3.  減小欄位長度

> 注意:一定不要手動去修改slave資料庫中的資料,需要給slave的使用者設定只讀。

至此,mysql的資料庫主從設定已經配置成功。在master中修改資料庫,會同步到slave中。

## Mycat基於MySQL的讀寫分離

Mycat不負責資料的同步,所以要還是要基於[MySQL的主從配置來實現讀寫分離](

)。

### 安裝Mycat

由於github限制,所以以後新版本從以下地址下載 http://dl.mycat.io

Linux建立資料夾/usr/local/mycat,進入資料夾,下載安裝包

$ wget http://dl.mycat.io/1.6.7.5/2020-3-3/Mycat-server-1.6.7.5-test-20200303154735-linux.tar.gz
$ tar -zxvf Mycat-server-1.6.7.5-test-20200303154735-linux.tar.gz
$ cd mycat
$ useradd mycat
$ chown -R mycat:mycat /usr/local/mycat/mycat
$ passwd mycat

// 配置hostname,新增以下配置
[root@localhost mycat] vim /etc/sysconfig/network
HOSTNAME=localhost(主機名)

// 檢視是否配置主機
$ vim /etc/hosts


將Mycat配置到環境變數中

$ vim /etc/profile
// 在最後新增
MYCAT_HOME=/usr/local/mycat/mycat
PATH=$MYCAT_HOME/bin:$PATH
export PATH

// 使配置生效
$ source /etc/profile


在master資料庫中新增user1(寫)、user2(只讀)兩個賬戶,並配置許可權。

配置mycat的schema.xml

<mycat:schema xmlns:mycat="http://io.mycat/">

<schema name="itools_simple" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
</schema>
<dataNode name="dn1" dataHost="localhost" database="itools_simple" />
<dataHost name="localhost" maxCon="1000" minCon="10" balance="0"
          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostM1" url="192.168.0.105:3306" user="user1" password="Root@123">
        <!-- 可以配置多個從庫 -->
        <readHost host="hostS2" url="127.0.0.1:3306" user="user2" password="Root@123" />
    </writeHost>
</dataHost>

</mycat:schema>


配置mycat的server.xml,增加兩個使用者

Root@123 itools_simple itools_simple Root@123 itools_simple true itools_simple ```

啟動Mycat

啟動mycat

$ mycat start
Starting Mycat-server...

檢視啟動日誌

$ cat wrapper.log
MyCAT Server startup successfully. see logs in logs/mycat.log

使用客戶端連線mycat

使用SQLyog連線(使用此方式連線,不能直接通過點選表檢視資料)

使用Navicat連線

可通過客戶端直接檢視master資料,也可通過修改mycat資料,檢視master和slave的資料是否會同步

SpringBoot 整合 MyCat 實現讀寫分離

  • 首先需要配置好資料庫的主從關係。

  • 配置好MyCat服務。

  • 實現MyCat與MySQL讀寫分離。

新增依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.23</version>
</dependency>

建立資料來源

package com.muycode.itoolsimple.datasource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    /**
     * 建立可讀資料來源
     *
     * @return
     */
    @Bean(name = "selectDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.select")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 建立可寫資料來源
     *
     * @return
     */
    @Bean(name = "updateDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.update")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }
}

設定資料來源

package com.muycode.itoolsimple.datasource;

import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Lazy(false)
public class DataSourceContextHolder {

    /**
     * 採用ThreadLocal 儲存本地多資料來源
     */
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    /**
     * 設定資料來源型別
     *
     * @param dbType
     */
    public static void setDbType(String dbType) {
        contextHolder.set(dbType);
    }

    /**
     * 獲取資料來源型別
     */
    public static String getDbType() {
        return contextHolder.get();
    }

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

返回資料來源

package com.muycode.itoolsimple.datasource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Component
@Primary
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Autowired
    @Qualifier("selectDataSource")
    private DataSource selectDataSource;

    @Autowired
    @Qualifier("updateDataSource")
    private DataSource updateDataSource;

    /**
     * 返回生效的資料來源名稱
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDbType();
    }

    /**
     * 配置資料來源資訊
     */
    @Override
    public void afterPropertiesSet() {
        Map<Object, Object> map = new HashMap<>(16);
        map.put("selectDataSource", selectDataSource);
        map.put("updateDataSource", updateDataSource);
        setTargetDataSources(map);
        setDefaultTargetDataSource(updateDataSource);
        super.afterPropertiesSet();
    }
}

建立切面,動態設定資料來源

package com.muycode.itoolsimple.datasource;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Lazy(false)
@Order(0) // Order設定AOP執行順序 使之在資料庫事務上先執行
public class DataSourceOptionAop {

    /**
     * 可讀資料來源
     */
    private final static String DATASOURCE_TYPE_SELECT = "selectDataSource";
    /**
     * 可寫資料來源
     */
    private final static String DATASOURCE_TYPE_UPDATE = "updateDataSource";

    /**
     * 建立切面,根據方法型別選擇不同的資料來源
     *
     * @param joinPoint
     */
    @Before("execution(* com.muycode.itoolsimple.service.*.*(..))")
    public void process(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        System.out.print("=========== " + methodName);
        if (methodName.startsWith("get") || methodName.startsWith("count") || methodName.startsWith("find")
                || methodName.startsWith("list") || methodName.startsWith("select") || methodName.startsWith("check")
                || methodName.startsWith("query")) {
            DataSourceContextHolder.setDbType(DATASOURCE_TYPE_SELECT);
            System.out.println("-----------------使用selectDataSource資料來源-------------------");
        } else {
            DataSourceContextHolder.setDbType(DATASOURCE_TYPE_UPDATE);
            System.out.println("-----------------使用updateDataSource資料來源-------------------");
        }
    }
}

輸出結果

=========== getByUsername-----------------使用selectDataSource資料來源-------------------
=========== getPermissionStringByUserId-----------------使用selectDataSource資料來源-------------------
=========== getPermissionByUserId-----------------使用selectDataSource資料來源-------------------


### 最後

小編在這裡分享些我自己平時的學習資料,由於篇幅限制,pdf文件的詳解資料太全面,細節內容實在太多啦,所以只把部分知識點截圖出來粗略的介紹,每個小節點裡面都有更細化的內容!

**[CodeChina開源專案:【一線大廠Java面試題解析+核心總結學習筆記+最新講解視訊】](https://ali1024.coding.net/public/P7/Java/git)**

**程式設計師程式碼面試指南 IT名企演算法與資料結構題目最優解**

這是” 本程式設計師面試寶典!書中對IT名企程式碼面試各類題目的最優解進行了總結,並提供了相關程式碼實現。針對當前程式設計師面試缺乏權威題目彙總這一-痛點, 本書選取將近200道真實出現過的經典程式碼面試題,幫助廣“大程式設計師的面試準備做到萬無一失。 “刷”完本書後,你就是“題王”!

![image.png](https://upload-images.jianshu.io/upload_images/24616006-044ac41e86c7e493.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

**《TCP-IP協議組(第4版)》**

本書是介紹TCP/IP協議族的經典圖書的最新版本。本書自第1版出版以來,就廣受讀者歡迎。

本書最新版進行」護元,以體境計算機網路技不的最新發展,全書古有七大部分共30草和7個附錄:第一部分介紹一些基本概念和基礎底層技術:第二部分介紹網路層協議:第三部分介紹運輸層協議;第四部分介紹應用層協議:第五部分介紹下一代協議,即IPv6協議:第六部分介紹網路安全問題:第七部分給出了7個附錄。

![image.png](https://upload-images.jianshu.io/upload_images/24616006-8976158861edfbc1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**Java開發手冊(嵩山版)**

這個不用多說了,阿里的開發手冊,每次更新我都會看,這是8月初最新更新的**(嵩山版)**

![image.png](https://upload-images.jianshu.io/upload_images/24616006-430c0003ec00a5c5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

**MySQL 8從入門到精通**

本書主要內容包括MySQL的安裝與配置、資料庫的建立、資料表的建立、資料型別和運算子、MySQL 函式、查詢資料、資料表的操作(插入、更新與刪除資料)、索引、儲存過程和函式、檢視、觸發器、使用者管理、資料備份與還原、MySQL 日誌、效能優化、MySQL Repl ication、MySQL Workbench、 MySQL Utilities、 MySQL Proxy、PHP操作MySQL資料庫和PDO資料庫抽象類庫等。最後通過3個綜合案例的資料庫設計,進步講述 MySQL在實際工作中的應用。

![image.png](https://upload-images.jianshu.io/upload_images/24616006-6685821f0213dcf8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**Spring5高階程式設計(第5版)**

本書涵蓋Spring 5的所有內容,如果想要充分利用這一領先的企業級 Java應用程式開發框架的強大功能,本書是最全面的Spring參考和實用指南。

本書第5版涵蓋核心的Spring及其與其他領先的Java技術(比如Hibemate JPA 2.Tls、Thymeleaf和WebSocket)的整合。本書的重點是介紹如何使用Java配置類、lambda 表示式、Spring Boot以及反應式程式設計。同時,將與企業級應用程式開發人員分享一些見解和實際經驗,包括遠端處理、事務、Web 和表示層,等等。

![image.png](https://upload-images.jianshu.io/upload_images/24616006-108fc1f48cad048d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**JAVA核心知識點+1000道 網際網路Java工程師面試題**

![image.png](https://upload-images.jianshu.io/upload_images/24616006-cfe84191535fdfbf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![image.png](https://upload-images.jianshu.io/upload_images/24616006-9401b4bc5fed51f5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


**企業IT架構轉型之道 阿里巴巴中臺戰略思想與架構實戰**

本書講述了阿里巴巴的技術發展史,同時也是-部網際網路技 術架構的實踐與發展史。

![image.png](https://upload-images.jianshu.io/upload_images/24616006-a5c5b06191e73819.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)