SpringBoot整合sharding-jdbc实现读写分离

一、什么是sharding-jdbc

Sharding-Jdbc在3.0后改名为Shardingsphere它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

应用场景:
数据库读写分离
数据库分表分库
相关资料:
Sharding-Jdbc官方网址: https://shardingsphere.apache.org/
改名新闻: https://www.oschina.net/news/95889/sharding-jdbc-change-to-sphere

二、Sharding-Jdbc与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 包的形式提供轻量级服务的。

这也就是之前在微服务中学习的SpringCloud Ribbon与Nginx区别。

三、SpringBoot整合sharding-jdbc实现读写分离

Sharding-Jdbc实现读写分离原理,非常容易。只需要在项目中集成主和从的数据源,Sharding-Jdbc自动根据DML和DQL 语句类型连接主或者从数据源。
sharding-jdbc没有帮我们实现主从同步,只是单纯实现判断语句类型是DML还是DQL语句。

maven依赖:

<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.0.1.RELEASEversion>
    <relativePath /> 
parent>
<properties>
    <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
    <java.version>1.8java.version>
properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>

    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <optional>trueoptional>
    dependency>
    <dependency>
        <groupId>com.baomidougroupId>
        <artifactId>mybatis-plus-boot-starterartifactId>
        <version>3.0-betaversion>
    dependency>
    <dependency>
        <groupId>io.shardingjdbcgroupId>
        <artifactId>sharding-jdbc-coreartifactId>
        <version>2.0.3version>
    dependency>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
    dependency>
dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-maven-pluginartifactId>
        plugin>
    plugins>

build>

application.yml

mybatis-plus:
  #  mapper-locations: classpath*:/mapper/*.xml
  global-config:
    db-config:
      column-underline: true
#shardingjdbc配置
sharding:
  jdbc:
    data-sources:
      ###配置第一个从数据库
      ds_slave_0:
        password: 123456
        jdbc-url: jdbc:mysql://192.168.112.143:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true
        driver-class-name: com.mysql.jdbc.Driver
        username: root
      ###主数据库配置
      ds_master:
        password: 123456
        jdbc-url: jdbc:mysql://192.168.112.142:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true
        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

配置类:
ShardingMasterSlaveConfig

@Data
@ConfigurationProperties(prefix = "sharding.jdbc")
public class ShardingMasterSlaveConfig {

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

	private MasterSlaveRuleConfiguration masterSlaveRule;
}

ShardingDataSourceConfig

@Configuration
@EnableConfigurationProperties(ShardingMasterSlaveConfig.class)
@Log4j2
// 读取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");
		return dataSource;
	}
}

controller:

@RestController
public class UserController {

	@Autowired
	private UserService userService;

	@RequestMapping("/findUser")
	public List<UserEntity> findUser() {
		return userService.findUser();
	}

	@RequestMapping("/insertUser")
	public String insertUser(String userName) {
		return userService.insertUser(userName) > 0 ? "success" : "fail";
	}

}

service:

@Service
public class UserService {
	@Autowired
	private UserMapper userMapper;

	// 使用读的数据源
	public List<UserEntity> findUser() {
		return userMapper.findUser();
	}

	// 使用写的数据源
	public int insertUser(String userName) {
		return userMapper.insertUser(userName);
	}

}

mapper:

public interface UserMapper {
	@Select("SELECT * FROM  user_info ")
	List<UserEntity> findUser();

	@Insert("insert into user_info values (#{userName}); ")
	int insertUser(@Param("userName") String userName);
}

entity:

@Data
public class UserEntity {

	private String userName;

}

启动类:

@SpringBootApplication
@MapperScan("com.xwhy.mapper")
public class AppMbatis {
	public static void main(String[] args) {

		SpringApplication.run(AppMbatis.class, args);
	}
}

四、读写分离原理

断点调试这个类就可以看到,插入和查询的时候回根据sql语句选择不同的数据源。
SpringBoot整合sharding-jdbc实现读写分离_第1张图片

你可能感兴趣的:(MySQL)