在个人看来,ShardingJDBC其实就是一个数据库中间件,因为其做到了无代码侵入这一点。再是SharingJDBC的使用关键主要在于分库的分库策略配置,而在分库策略配置中,ShardingJDBC已经支持了以数字类型,字符串类型等常规类型字段的分库算法,并且SQL解析功能也支持聚合、分组、排序、limit、or等查询,并支持Binding Table以及笛卡尔积表查询,支持for update行锁,最后就是SharingJDBC无需独立部署,只需依赖其jar包即可使用, 所以总体来说ShardingJDBC是一款使用方便,性能较好,功能相对全面的轻量级数据库中间件框架。
前置介绍:因为本次实践涉及多个微服务,所以是先将分库策略算法类根据个人实践需求封装成一个公共jar包,由该jar包引入ShardingJDBC相关jar包,再由各个微服务引入使用。各服务涉及的需要分库的表和字段以及分库的数据库连接还是需要在服务的文件里个性化配置的。
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>4.1.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.2.RELEASE</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.1.RELEASE</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
这里跟ShardingJDBC有关的就只有apache的这个,跟spring相关的是因为实践项目使用的是spring框架,封装为公共jar包后使用了spring的服务启动自动装配的功能。另外在后面代码实现片段涉及log日志打印这里没列相关包,这个是可以根据自己喜号选择包或者不打印过程日志。
引入服务需要依赖以下包:
第一个是引入一开始写的公共Jar包,二三是shardingjdbc名命和集成包
compile('com.公司内部路径.sharding.utils:commonsharding:上面公共包的版本')
compile('org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:4.1.1')
compile('org.apache.shardingsphere:sharding-jdbc-spring-namespace:4.1.1')
这一步是需要根据个人数据库表来决定的。本文中举例的服务为支付服务,所以相关的分库字段跟支付订单id,支付流水号,用户id有关。可以看到,分库的字段根据实际业务和表的复杂性其实绝对不是唯一的一个字段就可以对所有表都完成分库的,这里体现了一个核心的思想----规则传播。指先定义一个起源字段的分库规则,将其按照这个规则生成,再涉及到其他分库字段的使用时,其他分库字段的值也需要根据起源字段的值来生成,起源字段的分库规则就传播到了所有需要用于分库的字段,这样即使不同库表使用不同的字段分库,只要对应库表的分库字段是基于该传播链上的任意字段生成即可被分片算法获得相同的分库规则信息,通过此即可达到分库目的。分片规则字段其实也是使用一样的方法。
spring.profiles.include=shardingrules
spring.shardingsphere.datasource.names=ds-global,ds-0,ds-1
spring.shardingsphere.datasource.ds-global.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds-global.filters=dbauditlog
spring.shardingsphere.datasource.ds-global.driverClassName=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds-global.url=
spring.shardingsphere.datasource.ds-global.username=
spring.shardingsphere.datasource.ds-global.password =
spring.shardingsphere.datasource.ds-global.initial-size=4
spring.shardingsphere.datasource.ds-global.min-idle=5
spring.shardingsphere.datasource.ds-global.max-active=20
spring.shardingsphere.datasource.ds-global.max-wait=50000
spring.shardingsphere.datasource.ds-0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds-0.filters=dbauditlog
spring.shardingsphere.datasource.ds-0.driverClassName=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds-0.url=
spring.shardingsphere.datasource.ds-0.username=
spring.shardingsphere.datasource.ds-0.password =
spring.shardingsphere.datasource.ds-0.initial-size=4
spring.shardingsphere.datasource.ds-0.min-idle=5
spring.shardingsphere.datasource.ds-0.max-active=20
spring.shardingsphere.datasource.ds-0.max-wait=50000
spring.shardingsphere.datasource.ds-1.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds-1.filters = dbauditlog
spring.shardingsphere.datasource.ds-1.driverClassName = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds-1.url=
spring.shardingsphere.datasource.ds-1.username=
spring.shardingsphere.datasource.ds-1.password =
spring.shardingsphere.datasource.ds-1.initial-size = 4
spring.shardingsphere.datasource.ds-1.min-idle = 5
spring.shardingsphere.datasource.ds-1.max-active = 20
spring.shardingsphere.datasource.ds-1.max-wait = 50000
上述文件在application.properties文件中配置,这个也可以根据个人项目情况使用yaml或者代码注入。
文件第一行spring.profiles.include=shardingrules 这句话是引入了分片规则的配置文件,因为要提供给多个项目使用,减少对原服务配置的侵入,所以独立引入。
关键的key为spring.shardingsphere.datasource.names 这里定义了所有节点的库,分为全局库,和库0,库1。全局库的存在是因为有些枚举,配置表,字段异构表存在的库。库0,库1为实际业务数据需要存储的库。其他三大段都是对应库的连接配置,通过中间key的关键词可区分。
分片规则文件(根据个人情况定义):
sharding:
custom:
database-strategy: com.custom.sharding.CommonComplexShardingAlgorithm #分库算法策略指定类
script: ds-$->{0} #分库节点表达式
keys:
string-type: payment_order_id,payment_order_no,payment_detail_id,user_id #所有涉及的分库字段
spring:
shardingsphere:
sharding:
default-data-source-name: ds-global #默认节点指定的库
tables:
t_payment_order: #指定表名
actualDataNodes: ${sharding.custom.script}.t_payment_order #实际节点指定的库表
database-strategy:
complex:
sharding-columns: payment_order_id,user_id #该库涉及的分库字段
algorithm-class-name: ${sharding.custom.database-strategy} #指定分库策略
t_payment_coupon:
actualDataNodes: ${sharding.custom.script}.t_payment_coupon
database-strategy:
complex:
sharding-columns: payment_order_id
algorithm-class-name: ${sharding.custom.database-strategy}
t_payment_request:
actualDataNodes: ${sharding.custom.script}.t_payment_request
database-strategy:
complex:
sharding-columns: payment_order_no
algorithm-class-name: ${sharding.custom.database-strategy}
如附代码段,首先是指定一个分库算法类的全类名,再是定义分库的节点清单,最后则是配置需要用到分库的表,给其指定库节点,指定该表分库涉及的字段,指定分库算法(开头定义的),有多少表需要支持分库则定义多少组key,value。这里本人是用yaml文件写的配置,也可以根据实际个人喜好决定文件类型,文件格式,当然那就需要调整对应的配置读取方式。
写好对应配置文件之后就需要根据配置文件的格式,和字段key来实现shardingrules文件中算法类com.custom.sharding.CommonComplexShardingAlgorithm
CommonSharing:
SharingDataSourceSetUtil:
ShardingAutoConfiguration:
ShardingCustomProperties:
CommonComplexShardingAlgorithm:
通过上述图片的红色注释部分,总共就5个方法类,但其实关键的就两个CommonComplexShardingAlgorithm 和ShardingAutoConfiguration,其他都是一些数据封装对象或者公共方法封装类,涉及到分库算法的关键类为CommonComplexShardingAlgorithm 是需要继承ShardingJDBC提供的算法父类,再根据个人的一个分片规则定义来实现,ShardingAutoConfiguration是本次实践用了spring自动装配功能来实现的一个初始化方法。
CommonComplexShardingAlgorithm中核心的其实就是根据设别SQL中涉及的表和对应的条件字段来根据前面配置的分库规则识别出库节点返回,这样对应SQL在执行时就会操作指定节点的库。
引入自定义公共算法类jar包
compile('com.custom.sharding.utils:commonsharding:版本号)
SQL无需任何修改,只要对应表配置了分库策略,并且where条件字段包含分库字段即可由SharingJDBC框架识别操作不同的库
因篇幅问题不能全部显示,请点此查看更多更全内容