sharding-sphere是强大的读写分离、分表分库中间件,sharding-jdbc是sharding-sphere的核心模块。官方网站
springboot项目中集成sharding-jdbc也非常简单。
首先,引入sharding-jdbc和druid的jar包:
<!-- for spring boot -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
<!-- for spring namespace -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.13</version>
</dependency>
在properties或者yml中配置读写分离:
sharding.jdbc.datasource.names=master,slave0,slave1
sharding.jdbc.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.master.driver-class=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.master.url=xxx
sharding.jdbc.datasource.master.username=xxx
sharding.jdbc.datasource.master.password=xxx
sharding.jdbc.datasource.master.max-active=100
sharding.jdbc.datasource.master.min-idle=10
sharding.jdbc.datasource.master.initial-size=10
sharding.jdbc.datasource.master.test-on-borrow=true
sharding.jdbc.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.slave0.driver-class=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.slave0.url=xx
sharding.jdbc.datasource.slave0.username=xx
sharding.jdbc.datasource.slave0.password=xx
sharding.jdbc.datasource.slave0.max-active=100
sharding.jdbc.datasource.slave0.min-idle=10
sharding.jdbc.datasource.slave0.initial-size=10
sharding.jdbc.datasource.slave0.test-on-borrow=true
sharding.jdbc.datasource.slave1.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.slave1.driver-class=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.slave1.url=xx
sharding.jdbc.datasource.slave1.username=xx
sharding.jdbc.datasource.slave1.password=xx
sharding.jdbc.datasource.slave1.max-active=100
sharding.jdbc.datasource.slave1.min-idle=10
sharding.jdbc.datasource.slave1.initial-size=10
sharding.jdbc.datasource.slave1.test-on-borrow=true
sharding.jdbc.config.masterslave.name=ds-ms
sharding.jdbc.config.masterslave.master-data-source-name=master
sharding.jdbc.config.masterslave.slave-data-source-names=slave0,slave1
注意这段配置,除了前缀,后面部分都是druid连接池相关的参数。所以,如果你使用的不是 druid连接池,那么后面的参数也要根据连接池属性做相应的变更。
当然,如果你想配置更多连接池属性,也可以继续添加配置。
到这里,读写分离的配置就完成了,读写分离的功能已经实现了。具体什么情况下走master,什么情况下走slave,根据我的测试,直接写结论吧。
- sharding-jdbc是根据sql类型决定在master或者slave上面执行的,跟事务没关系
- 同一个方法中,遇到dml语句,那么该语句和其后面的所有sql都会在主库执行
查询sql默认会走slave库,但是一旦遇到dml语句,就会设置一个查询主库的标志,而这个对象是存在ThreadLocal中的,所以,其后的所以sql都会在主库执行。
强制读主
有些情况下,查询语句需要强制在master上执行,可以通过代码实现:
Object result;
HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
try {
result = xxxxx;
} finally {
hintManager.close();
}
return result;
为了方便,我们可以通过aop和自定注解实现这一功能:
// 定义注解
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MasterRoute {
//
}
// 定义aop
@Aspect
@Slf4j
@Component
public class MasterRouteAspect {
@Around(value = "@annotation(me.heys.anno.MasterRoute)")
public Object readMaster(ProceedingJoinPoint joinPoint) throws Throwable {
Object result;
HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
try {
result = joinPoint.proceed();
} finally {
hintManager.close();
}
return result;
}
}
这样,只需要在强制读主的方法上加@MasterRoute注解即可实现强制读主。
sharding-jdbc更多用于分表分库,用它只进行读写分离,有点杀鸡用牛刀的感觉。后面会介绍如何通过mysql的驱动实现读写分离。