quarkiverse / quarkus-shardingsphere-jdbc

Quarkus Sharding Sphere JDBC Extension
Apache License 2.0
9 stars 3 forks source link

quarkus上新增分片规则,请问如何实现? #145

Open MrYang-Jia opened 1 year ago

MrYang-Jia commented 1 year ago

目前我是在配置文件 org.apache.shardingsphere.sharding.spi.ShardingAlgorithm 里添加新的分片规则,结果发现配置表里引用的话会引用不到,请问如何实现

pom 配置如下

   <quarkus.platform.version>2.16.8.Final</quarkus.platform.version>

    <dependency>
      <groupId>io.quarkiverse.shardingsphere</groupId>
      <artifactId>quarkus-shardingsphere-jdbc</artifactId>
      <version>1.0.2</version>
    </dependency>

config.yaml

databaseName: sharding_db

dataSources:
  ds_0:
    dataSourceClassName: io.quarkiverse.shardingsphere.jdbc.QuarkusDataSource
    dsName: ds_0
  ds_1:
    dataSourceClassName: io.quarkiverse.shardingsphere.jdbc.QuarkusDataSource
    dsName: ds_1

rules:
  - !SHARDING
    tables:
      t_order:
        actualDataNodes: ds_${0..1}.t_order_${0..1}
        tableStrategy:
          standard:
            shardingColumn: order_id
            shardingAlgorithmName: t-order-inline
    ... ...

    defaultDatabaseStrategy:
      standard:
        shardingColumn: account_id  # 指定分片键值 该键值为 long 类型
        shardingAlgorithmName: hashModShardingAlgorithm   # 引用已存在的 hashModShardingAlgorithm 也是无效的,所以这里就不引用我自己编写的自定义算法了

application.properties 配置内容如下,不引入自定义分片规则的情况下可正常运行

quarkus.datasource.db-kind=shardingsphere
quarkus.datasource.jdbc.url=jdbc:shardingsphere:classpath:config.yaml

报错信息如下:

Failed to start application (with profile [dev]): org.apache.shardingsphere.sharding.exception.metadata.MissingRequiredShardingAlgorithmException: `hashModShardingAlgorithm` algorithm does not exist in database `sharding_db`.
    at org.apache.shardingsphere.sharding.checker.ShardingRuleConfigurationChecker.lambda$checkShardingStrategy$6(ShardingRuleConfigurationChecker.java:106)
    at org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions.checkState(ShardingSpherePreconditions.java:41)
    at org.apache.shardingsphere.sharding.checker.ShardingRuleConfigurationChecker.checkShardingStrategy(ShardingRuleConfigurationChecker.java:105)
    at org.apache.shardingsphere.sharding.checker.ShardingRuleConfigurationChecker.check(ShardingRuleConfigurationChecker.java:54)
    at org.apache.shardingsphere.sharding.checker.ShardingRuleConfigurationChecker.check(ShardingRuleConfigurationChecker.java:44)
    at org.apache.shardingsphere.infra.rule.builder.database.DatabaseRulesBuilder.build(DatabaseRulesBuilder.java:62)
    at org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase.create(ShardingSphereDatabase.java:87)
    at org.apache.shardingsphere.metadata.factory.ExternalMetaDataFactory.createGenericDatabases(ExternalMetaDataFactory.java:79)
    at org.apache.shardingsphere.metadata.factory.ExternalMetaDataFactory.create(ExternalMetaDataFactory.java:67)
    at org.apache.shardingsphere.mode.metadata.MetaDataContextsFactory.create(MetaDataContextsFactory.java:91)
    at org.apache.shardingsphere.mode.metadata.MetaDataContextsFactory.create(MetaDataContextsFactory.java:68)
    at org.apache.shardingsphere.mode.manager.standalone.StandaloneContextManagerBuilder.build(StandaloneContextManagerBuilder.java:53)
    at org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource.createContextManager(ShardingSphereDataSource.java:77)
    at org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource.<init>(ShardingSphereDataSource.java:65)
    at org.apache.shardingsphere.driver.api.ShardingSphereDataSourceFactory.createDataSource(ShardingSphereDataSourceFactory.java:93)
    at org.apache.shardingsphere.driver.api.yaml.YamlShardingSphereDataSourceFactory.createDataSource(YamlShardingSphereDataSourceFactory.java:153)
    at org.apache.shardingsphere.driver.api.yaml.YamlShardingSphereDataSourceFactory.createDataSource(YamlShardingSphereDataSourceFactory.java:95)
    at org.apache.shardingsphere.driver.jdbc.core.driver.DriverDataSourceCache.createDataSource(DriverDataSourceCache.java:51)
MrYang-Jia commented 1 year ago

image

zhfeng commented 1 year ago

Thanks @MrYang-Jia for your reporting!

So at first, is this configuration working on the plain shardingsphere or other runtime, such as spring-boot? If that is the case, does it work with JVM mode on quarkus?

MrYang-Jia commented 1 year ago

谢谢您的反馈,但是我使用的不是springBoot,不知道在quarkus上,我想这么实现自定义策略,我需要怎么做?有对应的实现案例吗?

Thank you for your feedback, but I am not using SpringBoot and I am not sure if I want to implement a custom policy on Quarkus. What do I need to do? Is there a corresponding implementation case?

Thanks @MrYang-Jia for your reporting!

So at first, is this configuration working on the plain shardingsphere or other runtime, such as spring-boot? If that is the case, does it work with JVM mode on quarkus?

zhfeng commented 1 year ago

As I far as Know, there was no such case before. So can you share with a project? Maybe I can take a look next week.

MrYang-Jia commented 1 year ago

@zhfeng 您好,我已经找到了解决方案,几个问题一起反馈下吧! 第一个: 自建 StandardShardingAlgorithm 规则类后,需要通过 config 配置文件里使用 type: CLASSBASED 的方式来加载对象类 然后如果使用这种模式的话,现有的 ClassBasedShardingAlgorithmFactory 对象类无法正常加载class 需要改写方法逻辑,主要部分为: First: After creating the StandardShardingAlgorithm rule class, you need to use type: class in the config configuration file BASED method to load object classes Then, if this mode is used, the existing ClassBasedShardingAlgorithmFactory object class cannot load the class properly The method logic needs to be rewritten, mainly including:

public static <T extends ShardingAlgorithm> T newInstance(String shardingAlgorithmClassName, Class<T> superShardingAlgorithmClass, Properties props) {
        try {
            Class<?> algorithmClass = 
// 这部分代码必须改写成如下方式,否则quarkus里加载不到对应的 class
// This part of the code must be rewritten as follows, otherwise the corresponding class cannot be loaded in Quarkus
Class.forName(shardingAlgorithmClassName,false,Thread.currentThread().getContextClassLoader());
            if (!superShardingAlgorithmClass.isAssignableFrom(algorithmClass)) {
                throw new ShardingAlgorithmClassImplementationException(shardingAlgorithmClassName, superShardingAlgorithmClass);
            } else {
                T result = (T) algorithmClass.getDeclaredConstructor().newInstance();
                result.init(convertToStringTypedProperties(props));
                return result;
            }
        } catch (ReflectiveOperationException var5) {
            throw new RuntimeException(var5);
        }
    }

第二个问题:5.4.0</shardingsphere.version> 构建规则时报 org.apache.shardingsphere.sharding.algorithm.sharding.complex.ComplexInlineShardingAlgorithm 找不到,原因是 5.4.0 调整了该类的位置,导致异常 ,5.4.0 的位置为 org.apache.shardingsphere.sharding.algorithm.sharding.inline.ComplexInlineShardingAlgorithm.class 所以要使用5.4.0版本的话,可以在对应的扩展里临时添加解决问题,或者是修改 5.4.0 的 shardingsphere jar包加载策略,从而解决问题 Second issue:5.4.0</shardingsphere. version>When building rules, the org. apache. shardingsphere. sharding. algorithm. sharding. complex. ComplexInlineShardingAlgorithm cannot be found. The reason is that 5.4.0 has adjusted the position of this class, resulting in an exception. The position of 5.4.0 is org. apache. shardingsphere. sharding. algorithm. sharding. inline. ComplexInlineShardingAlgorithm So if you want to use version 5.4.0, you can temporarily add a solution to the corresponding extension, or modify the shardingsphere jar package loading strategy of version 5.4.0 to solve the problem ============== 分享结束 ===================

MrYang-Jia commented 1 year ago

所以方便的话,最好还是您这里将这两个问题给修复下,因为quarkus是可以在 runtime 目录底下将对应有问题的类覆写,还有修正一些可能性的第三方jar包bug,感谢您抽空阅读完我编写的信息,谢谢 So, if it's convenient, it's best for you to fix these two issues here, because quarkus can overwrite the corresponding problematic classes in the runtime directory, and also fix some possible third-party jar package bugs. Thank you for taking the time to read the information I wrote. Thank you

zhfeng commented 1 year ago

@MrYang-Jia Sorry for the late reply and thanks for your investigation!

Is it possible to share your project with sharding algorithm?