You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by GitBox <gi...@apache.org> on 2021/10/14 15:16:24 UTC

[GitHub] [shardingsphere] linghengqian opened a new issue #13049: When choosing CLASS_BASED subdivision algorithm, the program did not execute class that implements StandardShardingAlgorithm init () function

linghengqian opened a new issue #13049:
URL: https://github.com/apache/shardingsphere/issues/13049


   ## Bug Report
   
   **For English only**, other languages will not accept.
   
   Before report a bug, make sure you have:
   
   - Searched open and closed [GitHub issues](https://github.com/apache/shardingsphere/issues).
   - Read documentation: [ShardingSphere Doc](https://shardingsphere.apache.org/document/current/en/overview).
   
   Please pay attention on issues you submitted, because we maybe need more details. 
   If no response anymore and we cannot reproduce it on current information, we will **close it**.
   
   Please answer these questions before submitting your issue. Thanks!
   
   ### Which version of ShardingSphere did you use?
   5.0.0-beta
   ### Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?
   ShardingSphere-JDBC
   ### Expected behavior
   When the program starts executing, ShardingJDBC finds the specific class by the fully qualified name of the sharding algorithm configured for application.properties and executes the init() function. When the program enters the dosharding() function, the init() code is already in effect.Below is the code for the algorithmClassName corresponding class and the configuration of application.properties.
   This class is I from org.apache.shardingsphere.sharding.algorithm.sharding.datetime.AutoIntervalShardingAlgorithm change to come over, so this class have some redundant code block.
   ```properties
   spring.shardingsphere.datasource.names=ds0
   spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
   spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
   spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=UTF-8
   spring.shardingsphere.datasource.ds0.username=root
   spring.shardingsphere.datasource.ds0.password=123456
   spring.shardingsphere.datasource.ds0.name=ShardingSphere
   spring.shardingsphere.datasource.ds0.maxActive=100
   spring.shardingsphere.datasource.ds0.initialSize=1
   spring.shardingsphere.datasource.ds0.maxWait=6000
   spring.shardingsphere.datasource.ds0.minIdle=1
   spring.shardingsphere.datasource.ds0.timeBetweenEvictionRunsMillis=60000
   spring.shardingsphere.datasource.ds0.minEvictableIdleTimeMillis=300000
   spring.shardingsphere.datasource.ds0.testWhileIdle=true
   spring.shardingsphere.datasource.ds0.testOnBorrow=false
   spring.shardingsphere.datasource.ds0.testOnReturn=false
   spring.shardingsphere.datasource.ds0.poolPreparedStatements=true
   spring.shardingsphere.datasource.ds0.maxOpenPreparedStatements=20
   spring.shardingsphere.datasource.ds0.asyncInit=true
   spring.shardingsphere.datasource.ds0.filters=stat
   spring.shardingsphere.datasource.ds0.use-global-datasource-stat=true
   spring.shardingsphere.datasource.ds0.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
   spring.shardingsphere.rules.sharding.tables.tb_result3_sharding_sphere.actual-data-nodes=ds0.tb_result3_sharding_sphere_$->{0..200}
   spring.shardingsphere.rules.sharding.tables.tb_result3_sharding_sphere.database-strategy.standard.sharding-column=datadate
   spring.shardingsphere.rules.sharding.tables.tb_result3_sharding_sphere.database-strategy.standard.sharding-algorithm-name=tb-result3-class-based
   spring.shardingsphere.rules.sharding.tables.tb_result3_sharding_sphere.key-generate-strategy.column=id
   spring.shardingsphere.rules.sharding.tables.tb_result3_sharding_sphere.key-generate-strategy.key-generator-name=snowflake
   spring.shardingsphere.rules.sharding.sharding-algorithms.tb-result3-class-based.type=CLASS_BASED
   spring.shardingsphere.rules.sharding.sharding-algorithms.tb-result3-class-based.props.strategy=STANDARD
   spring.shardingsphere.rules.sharding.sharding-algorithms.tb-result3-class-based.props.algorithmClassName=com.sg8000.spi.TbResult3ShardingAlgorithm
   spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
   spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=1014
   ```
   ```java
   package com.sg8000.spi;
   
   import com.google.common.collect.Range;
   import lombok.Getter;
   import lombok.Setter;
   import org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurationException;
   import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
   import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
   import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
   
   import java.text.DecimalFormat;
   import java.text.ParsePosition;
   import java.time.Duration;
   import java.time.LocalDateTime;
   import java.time.format.DateTimeFormatter;
   import java.time.format.DateTimeParseException;
   import java.util.Collection;
   import java.util.LinkedHashSet;
   import java.util.Properties;
   
   
   @Getter
   public final class TbResult3ShardingTestAlgorithm implements StandardShardingAlgorithm<Comparable<?>> {
       private static final String DATE_TIME_LOWER_KEY = "datetime-lower";
       private static final String DATE_TIME_UPPER_KEY = "datetime-upper";
       private static final String SHARDING_SECONDS_KEY = "sharding-seconds";
       private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.S]");
       @Setter
       private Properties props = new Properties();
       private LocalDateTime dateTimeLower;
       private long shardingSeconds;
       private int autoTablesAmount;
       private String tbResult3ShardingPrefix;
   
       @Override
       public void init() {
           dateTimeLower = getDateTime(DATE_TIME_LOWER_KEY);
           shardingSeconds = getShardingSeconds();
           autoTablesAmount = (int) (Math.ceil(parseDate("2022-12-31 23:59:59") / shardingSeconds) + 2);
           tbResult3ShardingPrefix = "tb_result3_sharding_sphere_";
       }
   
       private LocalDateTime getDateTime(final String dateTimeKey) {
           String value = "2021-01-01 00:00:00";
           try {
               return LocalDateTime.parse(value, DATE_TIME_FORMAT);
           } catch (final DateTimeParseException ex) {
               throw new ShardingSphereConfigurationException("无效的 %s, Datetime模式应该是 `yyyy-MM-dd HH:mm:ss[.S]`, 值是 `%s`", dateTimeKey, value);
           }
       }
   
       private long getShardingSeconds() {
           return Long.parseLong("604800");
       }
   
       @Override
       public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Comparable<?>> shardingValue) {
           String tableNameSuffix = String.valueOf(doSharding(parseDate(shardingValue.getValue())));
           for (String each : availableTargetNames) {
               if (each.endsWith(tbResult3ShardingPrefix + tableNameSuffix)) {
                   return each;
               }
           }
           return null;
       }
   
       @Override
       public Collection<String> doSharding(final Collection<String> availableTargetNames, final RangeShardingValue<Comparable<?>> shardingValue) {
           Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
           int firstPartition = getFirstPartition(shardingValue.getValueRange());
           int lastPartition = getLastPartition(shardingValue.getValueRange());
           for (int i = firstPartition; i <= lastPartition; i++) {
               for (String each : availableTargetNames) {
                   if (each.endsWith(tbResult3ShardingPrefix + i)) {
                       result.add(each);
                       break;
                   }
                   if (result.size() == availableTargetNames.size()) {
                       return result;
                   }
               }
           }
           return result;
       }
   
       private int doSharding(final long shardingValue) {
           String position = new DecimalFormat("0.00").format((float) shardingValue / shardingSeconds);
           return Math.min(Math.max(0, (int) Math.ceil(Float.parseFloat(position))), autoTablesAmount - 1);
       }
   
       private int getFirstPartition(final Range<Comparable<?>> valueRange) {
           return valueRange.hasLowerBound() ? doSharding(parseDate(valueRange.lowerEndpoint())) : 0;
       }
   
       private int getLastPartition(final Range<Comparable<?>> valueRange) {
           return valueRange.hasUpperBound() ? doSharding(parseDate(valueRange.upperEndpoint())) : autoTablesAmount - 1;
       }
   
       private long parseDate(final Comparable<?> shardingValue) {
           LocalDateTime dateValue = LocalDateTime.from(DATE_TIME_FORMAT.parse(shardingValue.toString(), new ParsePosition(0)));
           return Duration.between(dateTimeLower, dateValue).toMillis() / 1000;
       }
   
       @Override
       public String getType() {
           return null;
       }
   }
   ```
   ### Actual behavior
   When the custom class subdivision algorithm CLASS_BASED strategy defined as STANDARD, procedure not execute class that implements StandardShardingAlgorithm init () function.
   Through DEBUG, it can be found that the "public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Comparable<?>> shardingValue)" function under this class has got the parameter that should be initialized in the init() function as null, this Prove that the init() function was not successfully executed.
     The "private LocalDateTime getDateTime(final String dateTimeKey)" function called by the init() function did not throw an exception.
   The comment on the screenshot is a part of the project mark, which has no meaning with this Issue. The code is in the Expected behavior section of the Issue.
   
   ![image](https://user-images.githubusercontent.com/20187731/137346186-b87fcb36-eefd-4fe6-aa5e-0ca022a57a31.png)
   
   ![image](https://user-images.githubusercontent.com/20187731/137346392-5ad999c6-dfce-4ea4-9522-ecd43c4a187e.png)
   
   ### Reason analyze (If you can)
   
   ### Steps to reproduce the behavior, such as: SQL to execute, sharding rule configuration, when exception occur etc.
   
   ### Example codes for reproduce this issue (such as a github link).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@shardingsphere.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org