shardindjdbc支持读写分离
sql和源码
https://gitee.com/zhangjijige/shardingjdbc.git
配置
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
# 参数配置,显示 sql
props:
sql:
show: true
# 配置数据源
datasource:
# 主节点数据源
names: db0, db1, db2, db3
# db0数据源信息
db0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_0?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_2?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
db3:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/order_db_3?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
username: root
password: root
masterslave:
# 配置主从复制名称,可以取任意名称
name: ms
# 配置主库 master,负责数据写入
master-data-source-name: db0
# 配置从库 slave,负责数据读取
slave-data-source-names: db1,db2,db3
# 配置从节点的负载均衡策略,默认机制是round_robin,轮询
load-balance-algorithm-type: round_robin
mybatis:
mapper-locations: classpath:mapper/*.xml
查询数据的时候插入修改数据的时候,使用主库,查询数据的时候使用从库,从库默认是使用轮询的方式获取
解释一下从节点的均衡策略
解释之前先说一下 怎么用for循环遍历Iterable
@Data
public class SPILoader implements Iterable {
List<String> ls = new ArrayList<>();
@Override
public Iterator iterator(){
return new Iterator() {
Iterator<String> lsi = ls.iterator();
@Override
public boolean hasNext(){
return lsi.hasNext();
}
@Override
public Object next(){
return lsi.next();
}
};
}
public static void main(String[] args){
List<String> ls = new ArrayList<>();
ls.add("1");
ls.add("2");
ls.add("3");
ls.add("4");
SPILoader spiLoader = new SPILoader();
spiLoader.setLs(ls);
//没遍历一次就会执行上面的 hashnext和next方法
for(Object o : spiLoader){
System.out.println(o.toString());
}
}
}
在sharding中的使用
org.apache.shardingsphere.core.spi.NewInstanceServiceLoader#register
public static <T> void register(final Class<T> service) {
for (T each : ServiceLoader.load(service)) {
registerServiceClass(service, each);
}
}
为什么将这个呢,就是大名鼎鼎的spi模式的用法,spi最大的作用就是可扩展
在项目中按照上面的路径,创建一个文件,文件名称是接口名称,内容为接口的实现类的全路径即可
从库的均衡策略是就是通过spi的方式,从配置中获取的,示例中使用的是 round_robin
org.apache.shardingsphere.spi.masterslave.MasterSlaveLoadBalanceAlgorithm的实现类,会被spi获取到,通过loadTypeBasedServices方法的MasterSlaveLoadBalanceAlgorithm的getType方法判断使用哪个类作为均衡策略类
org.apache.shardingsphere.core.spi.algorithm.TypeBasedSPIServiceLoader#loadTypeBasedServices
在配置中把round_robin替换为约定好的标记,比如 my_round_robin,在MasterSlaveLoadBalanceAlgorithm实现类中,getType方法返回my_round_robin即可
在getDataSource方法中返回要查询的数据源
其余的比如id的生成策略,也是同样的方式,我要通过自己的方式生成id,也是用spi扩展,shardingjdbc的这种通过spi的扩展思想,是可以同运用在平时的生产中
主从分离还是比较好理解,那我在使用的时候,查询也想使用主库怎么办呢,可能会出现刚新增的数据,马上就要查看的情况,那就强制走主库,使用的是hint的HintManager管理者instance.setMasterRouteOnly();只从主库获取数据即可.