总文档 :文章目录
Github : github.com/black-ant
一 . 前言
本来也没打算看读写分离的代码 , 但是…他他他又出问题了 , 按照官方文档尝试配置了 读写分离后 , 并没有出现期待的结果
不过幸运的是 , 能跑起来 , 大概率就是读写分离的逻辑没有生效
二 . 源码分析
和上一篇最大的难点就是 , 不知道从哪里开始看起…
这个时候官方文档的作用就出来了 , 它告诉我有一个接口 ShardingSphereAlgorithm , 于是查找其实现类 , 有所发现
可以看到 ,读写分离在 Sharding 中也有着负载均衡的作用 , 对应的接口为 ReplicaLoadBalanceAlgorithm
2.1 入口查找
先看一下接口中需要实现什么
1 | java复制代码// 接口中提供了一个待实现的方法 |
我们随机选择一个 ShardingSphereAlgorithm 逆推一下流程 , 最终发现了类
- ReplicaQueryDataSourceRouter # route
- ReplicaQuerySQLRouter # createRouteContext
- PartialSQLRouteExecutor # route
我们按照这个流程逆推一下 :
Step End : ReplicaQueryDataSourceRouter 最终规则处理
1 | java复制代码C55- ReplicaQueryDataSourceRouter |
一路往上 , 发现了核心处理类 KernelProcessor , 到了这里就基本能确定 , 还是会通过ShardingSpherePreparedStatement 处理
2.2 正向流程梳理
知道了主流程 , 我们就可以推断出正向流程 :
- C74- ShardingSpherePreparedStatement
- C101- KernelProcessor
- M101_01- generateExecutionContext
- C102- SQLRouteEngine
- route
- C103- PartialSQLRouteExecutor
- route
- C60- ReplicaQuerySQLRouter
- createRouteContext – 终于到了这个核心的地方
Step 1 : ShardingSpherePreparedStatement 创建 ExecutionContext
直接来到主入口进行调试 : ShardingSpherePreparedStatement , 其中有2个主要的方法 executeQuery() / executeUpdate()
上一次说了executeUpdate , 这一次主要走 executeQuery
1 | java复制代码C74- ShardingSpherePreparedStatement |
这是一个核心的锚点 , 找到了这个点 , 后面的就好分析了
PS : 后续整体流程和之前看的一样 , 主要是以下流程
Step 2 : KernelProcessor 构建 ExecutionContext 流程主逻辑
1 | java复制代码 |
PS:M101_01_10 相关属性一览
Step 3 : PartialSQLRouteExecutor 通过 rules 生成 result
注意 , 这里会根据是否已经创建了 RouteUnits 选择是否创建还是添加
处理流程 , 下面2个 问题解决完成后 , 配置正常 , 此时可以看到 rule 存在
1 | java复制代码// 我们根据上面2个流程着重分析其中2步 |
PS:M101_01_02 rules 列表
Step 4 : ReplicaQuerySQLRouter / rules 处理主逻辑
这个逻辑中有 2个重要的方法
- createRouteContext : 创建 RouteContext
- decorateRouteContext : 补充 RouteContext
1 | java复制代码C60- ReplicaQuerySQLRouter |
Step 补充环节 : Rule 的处理流程
rules 的处理流程主要是以下几步 :
- SQLRouteEngine : route 处理引擎 , 开始处理 route
- PartialSQLRouteExecutor : 选择哪种核心方式
- ReplicaQuerySQLRouter : 核心的处理方式
- ReplicaQueryDataSourceRouter : 调用算法获取Source 名称
- RoundRobinReplicaLoadBalanceAlgorithm : 算法核心
rules 的构建流程主要是以下几步 :
- SchemaContextsBuilder : 构建 ContextsBuilder
- ShardingSphereRulesBuilder : 通过 rules 配置执行 build 主逻辑
- ReplicaQueryRuleBuilder : 拿到相关配置 , 构建主要的 Rule
- ReplicaQueryRule : 被构建的对象
PS:M101_01_01 rules 集合
第一次运行的时候发现 rule 为空 , 明白找到了第一个问题 , 配置实际上是缺失的 , 看一下rule 的继承体系
1 | java复制代码// 很明显 , 看到了一个 ReplicaQueryRule , 进去看看 |
Step 附录 : 读写分离的相关配置分析方式
配置类还是之前的几个
- SpringBootConfiguration
- YamlReplicaQueryRuleSpringBootConfiguration : spring.shardingsphere.rules
- YamlReplicaQueryRuleConfiguration : replicaQuery
- Map<String, YamlReplicaQueryDataSourceRuleConfiguration> : dataSources
- Map<String, YamlShardingSphereAlgorithmConfiguration> : loadBalancers
- YamlReplicaQueryRuleConfiguration : replicaQuery
我算是明白了 , 也不知道是不是找的文档不对 ,指望官方文档还是不行的 , 最后还是要靠自己
这一小节就是如果通过 Sharding 的 配置类 Bean , 反推出相关的配置.
PS:M51_01_01 配置类的推测
1 | java复制代码// 点开可以看到 , 其中只有2个属性 |
1 | java复制代码我们按照这个方法 , 结合官方文档 , 逆推一下 , 可以找到如下几个类 : |
这不看源码你叫我怎么猜的出来??????????????
三 . 配置
这里把完整的配置贴出来
1 | properties复制代码server.port=8085 |
总结
读写分离其实很简单 , 主要是不知道新版的配置方式 , 希望这篇文档对以后排错能有所帮助
本文转载自: 掘金