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,根據我的測試,直接寫結論吧。
- 如果不是事務方法,那么所有的查詢都一定會走slave庫;
- 如果是事務方法,那么第一個insert/update/delete語句之前的查詢都會走slave庫,之后的所有sql語句都會走master庫;
事務方法中,查詢sql默認會走slave庫,但是一旦遇到insert/update/delete語句,就會設置一個查詢主庫的標志,而這個對象是存在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的驅動實現讀寫分離。