Appearance
ShardingSphere由JDBC、Proxy和Sidecar(规划中)构成,其中Sidecar还在规划中暂不使用,JDBC定位为轻量级Java框架,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动; Proxy定位为透明化的数据库代理端,目前提供MySQL和PostgreSQL版本,向应用程序完全透明,可直接当做 MySQL/PostgreSQL 使用;
总结来说,JDBC相当于是一个java框架,通过jar包来提供服务,管理多个数据库的各项功能;而Proxy则是一个中间件,对代码无侵入性,直接管理各个数据库,应用程序直接连接Proxy就和使用MySQL一样简单。
本片文章讲解ShardingSphere-JDBC中的读写分离功能,首先需要搭建SpringBoot工程项目,然后按照官方文档一步步进行读写分离配置,当然前提条件是MySQL数据库已经进行了主从数据库的配置。
1. 创建SpringBoot程序
xml
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.1.1</version>
</dependency>
</dependencies>
1.1 创建实体类
java
@TableName("t_user")
@Data
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String uname;
}
1.2 创建Mapper
java
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
1.3 配置读写分离
application.properties:
properties
# 应用名称
spring.application.name=sharging-jdbc-demo
# 开发环境设置
spring.profiles.active=dev
# 内存模式
spring.shardingsphere.mode.type=Memory
# 配置真实数据源
spring.shardingsphere.datasource.names=master,slave1,slave2
# 配置第 1 个数据源
spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://192.168.100.201:3306/db_user
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 配置第 2 个数据源
spring.shardingsphere.datasource.slave1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave1.jdbc-url=jdbc:mysql://192.168.100.201:3307/db_user
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=123456
# 配置第 3 个数据源
spring.shardingsphere.datasource.slave2.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave2.jdbc-url=jdbc:mysql://192.168.100.201:3308/db_user
spring.shardingsphere.datasource.slave2.username=root
spring.shardingsphere.datasource.slave2.password=123456
# 读写分离类型,如: Static,Dynamic
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.type=Static
# 写数据源名称
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.write-data-source-name=master
# 读数据源名称,多个从数据源用逗号分隔
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.read-data-source-names=slave1,slave2
# 负载均衡算法名称
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.load-balancer-name=alg_round
# 负载均衡算法配置
# 负载均衡算法类型
spring.shardingsphere.rules.readwrite-splitting.load-balancers.alg_round.type=ROUND_ROBIN
spring.shardingsphere.rules.readwrite-splitting.load-balancers.alg_random.type=RANDOM
spring.shardingsphere.rules.readwrite-splitting.load-balancers.alg_weight.type=WEIGHT
spring.shardingsphere.rules.readwrite-splitting.load-balancers.alg_weight.props.slave1=1
spring.shardingsphere.rules.readwrite-splitting.load-balancers.alg_weight.props.slave2=2
# 打印SQl
spring.shardingsphere.props.sql-show=true
2. 配置分析
- 模式配置:模式配置,测试时使用内存模式,运行模式说明可点击跳转
- 数据源配置:第二步就是数据源配置,给三个数据源分别起了3个名字分别是master、slave1、slave2,在配置数据源时指定这些名字。
- 读写分离:读写分离配置,master是写数据源,slave1,slave2是读数据源,MySQL配置了主从数据库,主数据库发生变动,从数据库会跟着改变。
- 负载均衡算法:负载均衡算法官方文档有提到,包含ROUND_ROBIN(轮询算法)、RANDOM(随机访问算法)、WEIGHT(权重访问算法)
3.读写分离功能测试
读写分离测试,写入数据发现三台数据库均能写入数据,读数据发现读出来的是两台从库的数据,uname
字段的第二条记录在三台机器都是不一样的,多测试即便发现读出来的是两台从库的数据。至此,读写分离功能测试正常。
java
@SpringBootTest
class DistributedShardingApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert() {
User user = new User();
user.setUname("张三丰");
userMapper.insert(user);
}
@Test
public void testSelect() {
List<User> userList1 = userMapper.selectList(null);
List<User> userList2 = userMapper.selectList(null);
System.out.println(userList1);
System.out.println(userList2);
}
}
也可以在web请求中测试负载均衡
java
@RestController
@RequestMapping("/userController")
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("selectAll")
public void selectAll(){
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
}
事务测试
为了保证主从库间的事务一致性,避免跨服务的分布式事务,ShardingSphere-JDBC的主从模型中,事务中的数据读写均用主库
。
- 不添加@Transactional:insert对主库操作,select对从库操作
- 添加@Transactional:则insert和select均对主库操作
- **注意:**在JUnit环境下的@Transactional注解,默认情况下就会对事务进行回滚(即使在没加注解@Rollback,也会对事务回滚)
java
@Test
@Transactional //开启事务
public void testTrans() {
User user = new User();
user.setUname("铁锤");
userMapper.insert(user);
List<User> users = userMapper.selectList(null);
}