背景信息

对于 org.apache.shardingsphere.driver.ShardingSphereDriver 的驱动类, 通过实现 org.apache.shardingsphere.infra.url.ShardingSphereURLLoader 的 SPI, 可允许从多种来源和 File System 获取并解析为 ShardingSphere 的 YAML 配置文件。 如无特定声明,以下实现均采用 YAML 1.1 作为 YAML 的编写规范, 这并不阻止 org.apache.shardingsphere.infra.url.ShardingSphereURLLoader 的自定义实现从 XML 或 JSON 等文件手动转化为 YAML。

在解析并加载 YAML 文件为 ShardingSphere 的元数据后, 会再次通过模式配置的相关配置决定下一步行为。讨论两种情况,

  1. 元数据持久化仓库中不存在 ShardingSphere 的元数据,本地元数据将被存储到元数据持久化仓库。
  2. 元数据持久化仓库中已存在 ShardingSphere 的元数据,无论是否与本地元数据相同,本地元数据将被元数据持久化仓库的元数据覆盖。

对元数据持久化仓库的配置需参考元数据持久化仓库

加载配置文件的方式

从类路径中加载配置文件

配置文件为 xxx.yaml,当placeholder-typenone或不标明时,配置文件格式与 YAML 配置 一致。 当placeholder-type存在且不为none时,配置文件格式的定义参考本文的JDBC URL 参数一节。

用例:

  • jdbc:shardingsphere:classpath:config.yaml
  • jdbc:shardingsphere:classpath:config.yaml?placeholder-type=none
  • jdbc:shardingsphere:classpath:config.yaml?placeholder-type=environment
  • jdbc:shardingsphere:classpath:config.yaml?placeholder-type=system_props

从绝对路径中加载配置文件

配置文件为 xxx.yaml,当placeholder-typenone或不标明时, 配置文件格式与 YAML 配置 一致。 当placeholder-type存在且不为none时,配置文件格式的定义参考本文的JDBC URL 参数一节。

用例:

  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml
  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=none
  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=environment
  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=system_props

JDBC URL 参数

对于 org.apache.shardingsphere.infra.url.ShardingSphereURLLoader 的实现,并非所有的 JDBC URL 参数都必须被解析, 这涉及到如何实现 org.apache.shardingsphere.infra.url.ShardingSphereURLLoader.load()

placeholder-type

存在 placeholder-type 属性用于可选的加载包含动态占位符的配置文件,placeholder-type 存在默认值为none。 当 placeholder-type 设置为非 none 时, 在涉及的 YAML 文件中允许通过动态占位符设置特定 YAML 属性的值,并配置可选的默认值。 动态占位符的名称和其可选的默认值通过::分割, 在最外层通过$${}包裹。

讨论两种情况,

  1. 当对应的动态占位符的值不存在时,此 YAML 属性的值将被设置为::右侧的默认值。
  2. 当对应的动态占位符的值和::右侧的默认值均不存在时,此属性将被设置为空。

none

配置文件为 xxx.yaml,配置文件格式与 YAML 配置 一致。

用例:

  • jdbc:shardingsphere:classpath:config.yaml
  • jdbc:shardingsphere:classpath:config.yaml?placeholder-type=none
  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml
  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=none

environment

加载包含环境变量的配置文件时,需将 placeholder-type置为environment,这常用于 Docker Image 的部署场景。 配置文件为 xxx.yaml,配置文件格式与 YAML 配置 基本一致。

假设存在以下一组环境变量,

  1. 存在环境变量 FIXTURE_JDBC_URLjdbc:h2:mem:foo_ds_1;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL
  2. 存在环境变量 FIXTURE_USERNAMEsa

则对于以下 YAML 文件的截取片段,

  1. ds_1:
  2. dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  3. driverClassName: $${FIXTURE_DRIVER_CLASS_NAME::org.h2.Driver}
  4. jdbcUrl: $${FIXTURE_JDBC_URL::jdbc:h2:mem:foo_ds_do_not_use}
  5. username: $${FIXTURE_USERNAME::}
  6. password: $${FIXTURE_PASSWORD::}

此 YAML 截取片段将被解析为,

  1. ds_1:
  2. dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  3. driverClassName: org.h2.Driver
  4. jdbcUrl: jdbc:h2:mem:foo_ds_1;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL
  5. username: sa
  6. password:

用例:

  • jdbc:shardingsphere:classpath:config.yaml?placeholder-type=environment
  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=environment

system_props

加载包含系统属性的配置文件时,需将 placeholder-type置为system_props。 配置文件为 xxx.yaml,配置文件格式与 YAML 配置 基本一致。

假设存在以下一组系统属性,

  1. 存在系统属性 fixture.config.driver.jdbc-urljdbc:h2:mem:foo_ds_1;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL
  2. 存在系统属性 fixture.config.driver.usernamesa

则对于以下 YAML 文件的截取片段,

  1. ds_1:
  2. dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  3. driverClassName: $${fixture.config.driver.driver-class-name::org.h2.Driver}
  4. jdbcUrl: $${fixture.config.driver.jdbc-url::jdbc:h2:mem:foo_ds_do_not_use}
  5. username: $${fixture.config.driver.username::}
  6. password: $${fixture.config.driver.password::}

此 YAML 截取片段将被解析为,

  1. ds_1:
  2. dataSourceClassName: com.zaxxer.hikari.HikariDataSource
  3. driverClassName: org.h2.Driver
  4. jdbcUrl: jdbc:h2:mem:foo_ds_1;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL
  5. username: sa
  6. password:

在实际情况下,系统变量通常是动态定义的。假设如上系统变量均未定义,存在包含如上 YAML 截取片段的 YAML 文件 config.yaml, 可参考如下方法,使用 HikariCP Java API 创建 DataSource 实例。

  1. import com.zaxxer.hikari.HikariConfig;
  2. import com.zaxxer.hikari.HikariDataSource;
  3. import javax.sql.DataSource;
  4. public class ExampleUtils {
  5. public DataSource createDataSource() {
  6. HikariConfig config = new HikariConfig();
  7. config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver");
  8. config.setJdbcUrl("jdbc:shardingsphere:classpath:config.yaml?placeholder-type=system_props");
  9. try {
  10. assert null == System.getProperty("fixture.config.driver.jdbc-url");
  11. assert null == System.getProperty("fixture.config.driver.username");
  12. System.setProperty("fixture.config.driver.jdbc-url", "jdbc:h2:mem:foo_ds_1;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL");
  13. System.setProperty("fixture.config.driver.username", "sa");
  14. return new HikariDataSource(config);
  15. } finally {
  16. System.clearProperty("fixture.config.driver.jdbc-url");
  17. System.clearProperty("fixture.config.driver.username");
  18. }
  19. }
  20. }

用例:

  • jdbc:shardingsphere:classpath:config.yaml?placeholder-type=system_props
  • jdbc:shardingsphere:absolutepath:/path/to/config.yaml?placeholder-type=system_props

其他实现

具体可参考 https://github.com/apache/shardingsphere-plugin