JAVA面试题分享四百九十:Sharding-jdbc:3分钟搞定读写分离

目录

介绍

和Mycat区别

原理

实现

1、核心依赖

2、application.yml配置

3、config配置类

1)、config读取sharding-jdbc的配置

2)、config读取ds_master主数据源和读写分离配置

4、测试接口

5、效果

总结


前言

今天来讲讲Sharding-Jdbc如何实现读写分离,话不多说,直接开干。

介绍

Sharding-Jdbc3.0后改名为ShardingSphere,它由Sharding-JDBCSharding-ProxySharding-Sidecar这3款相互独立的产品组成。

和Mycat区别

Mycat是一个基于第三方应用中间件数据库代理框架,客户端所有的jdbc请求都必须要先交给MyCat,再由MyCat转发到具体的真实服务器中。

Sharding-Jdbc是一个Jar形式,在本地应用层重写Jdbc原生的方法,实现数据库分片形式。

所以说,MyCat属于服务器端数据库中间件,而Sharding-Jdbc是一个本地数据库中间件框架。

从设计理念上看确实有一定的相似性。主要流程都是:SQL 解析 -> SQL 路由 -> SQL 改写 -> SQL 执行 -> 结果归并。

但架构设计上是不同的。Mycat 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个 MySQL 数据库,而 Sharding-JDBC 是基于 JDBC 的扩展,是以 jar 包的形式提供轻量级服务的。

原理

Sharding-Jdbc实现读写分离原理,非常容易。只需要在项目中集成的数据源,Sharding-Jdbc自动根据DMLDQL语句类型连接或者数据源。

注意: Sharding-Jdbc只是实现连接主或者从数据源,不会实现主从复制功能,需要自己配置数据库自带主从复制方式。

查看MasterSlaveDataSource即可查看该类getDataSource方法获取当前数据源名称。

实现

1、核心依赖
<!-- sharding-jdbc 依赖 -->
<dependency>
<groupId>io.shardingjdbc</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>2.0.3</version>
</dependency>
2、application.yml配置
server:
  port: 8080
mybatis-plus:
  mapper-locations: classpath*:/mapper/*.xml
  #实体扫描,多个package用逗号或者分号分隔
 typeAliasesPackage: com.jidian.sharding.*.entity
  global-config:
    db-config:
      column-underline: true
#shardingjdbc配置
sharding:
  jdbc:
    data-sources:
     ###配置第一个从数据库
      ds_slave_0:
        password: 123456
        jdbc-url: jdbc:mysql://192.168.1.121:3307/mydatabase?useUnicode=true&characterEncoding=utf-8&useSSL=false
        driver-class-name: com.mysql.jdbc.Driver
        username: root
      ###主数据库配置
      ds_master:
        password: 123456
        jdbc-url: jdbc:mysql://192.168.1.129:3306/mydatabase?useUnicode=true&characterEncoding=utf-8&useSSL=false
        driver-class-name: com.mysql.jdbc.Driver
        username: root
    ###配置读写分离
    master-slave-rule:
    ###配置从库选择策略,提供轮询与随机,这里选择用轮询
      load-balance-algorithm-type: round_robin
      ####指定从数据库
      slave-data-source-names: ds_slave_0
      ####读写分离名称,随便起。
      name: ds_ms
      ####指定主数据库
      master-data-source-name: ds_master
3、config配置类
1)、config读取sharding-jdbc的配置
import com.zaxxer.hikari.HikariDataSource;
import io.shardingjdbc.core.api.config.MasterSlaveRuleConfiguration;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.HashMap;
import java.util.Map;

/**
* @作者: 程序员济癫
*/
@Data
@ConfigurationProperties(prefix = "sharding.jdbc")
public class ShardingMasterSlaveConfig {

    // 存放本地多个数据源
    private Map<String, HikariDataSource> dataSources = new HashMap<>();

    private MasterSlaveRuleConfiguration masterSlaveRule;

}
2)、config读取ds_master主数据源和读写分离配置
import com.google.common.collect.Maps;
import io.shardingjdbc.core.api.MasterSlaveDataSourceFactory;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
@EnableConfigurationProperties(ShardingMasterSlaveConfig.class)
@ Slf4j
// 读取ds_master主数据源和读写分离配置
@ ConditionalOnProperty({
    "sharding.jdbc.data-sources.ds_master.jdbc-url",
    "sharding.jdbc.master-slave-rule.master-data-source-name"
})
public class ShardingDataSourceConfig {

    @Autowired
    private ShardingMasterSlaveConfig shardingMasterSlaveConfig;

    @Bean
    public DataSource masterSlaveDataSource() throws SQLException {

        final Map < String, DataSource > dataSourceMap = Maps.newHashMap();
        dataSourceMap.putAll(shardingMasterSlaveConfig.getDataSources());
        final Map < String, Object > newHashMap = Maps.newHashMap();
        // 创建 MasterSlave数据源
        DataSource dataSource = MasterSlaveDataSourceFactory.createDataSource(dataSourceMap,
            shardingMasterSlaveConfig.getMasterSlaveRule(), newHashMap);
        log.info("masterSlaveDataSource config complete");
        log.info("getDataSources: {}", shardingMasterSlaveConfig.getDataSources());
        log.info("getMasterSlaveRule: {}", shardingMasterSlaveConfig.getMasterSlaveRule());
        return dataSource;
    }

}
4、测试接口

写两个接口分别测试entitymapperservice等省略。

@RestController
@RequestMapping("/user")
public class TbUserController {

    @Autowired
    private ITbUserService userService;

    @GetMapping("/userList")
    public ResponseEntity selectUsers() {

        List < TbUser > userList = userService.getBaseMapper().selectList(null);
        if (userList == null) {
            return new ResponseEntity(false, StatusCode.ERROR, "获取用户列表失败");
        }
        return new ResponseEntity(true, StatusCode.OK, "获取用户列表成功", userList);
    }

    @PostMapping("/insertUser")
    public ResponseEntity insertUser(@RequestBody TbUser user) {

        if (user == null) {
            return new ResponseEntity(false, StatusCode.ERROR, "新增用户失败");
        }
        userService.getBaseMapper().insert(user);
        return new ResponseEntity(true, StatusCode.OK, "新增用户成功", user);
    }

}

 

5、效果

先查出所有看是否正常

然后把从库数据删除一条或多条,再次查询看看。

 

再次查询,发现没有了。

说明,查询走的是从库

最后再测试一下插入,看主库是否会有数据!

读写分离是OK的!

总结

Sharding-Jdbc对于中小企业而言,确实是一款数据库中间件利器读写分离分库分表都很好接入。

但这里作者君要稍微提一点自己的见解,以目前的趋势来看,未来更多事情由数据库自己完成是一种走向,不少大企业开始制作单独的云数据库产品,附带了许多衍生的功能,就可以窥见一二。

因此,大家对于这种工具,需要了解,但不必花费太多时间,除非你有兴趣研究它的实现。

咱们,还是多把时间精力花在刀刃上,先把公司的业务吃透,有了立身之本,再考虑技术层面的东西。

好了,今天的小知识你学会了吗?

 

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值