budo-sharding-proxy

This commit is contained in:
黎明伟 2020-06-18 10:53:07 +08:00
parent 82fd3cddb3
commit 570b98681f
8 changed files with 357 additions and 1 deletions

View File

@ -0,0 +1,5 @@
# budo-sharding-proxy
[shardingsphere-proxy-boot-mybatis-example](https://github.com/apache/shardingsphere/tree/master/examples/shardingsphere-proxy-example/shardingsphere-proxy-boot-mybatis-example/src/main/resources/conf)
[shardingsphere-proxy-hint-example](https://github.com/apache/shardingsphere/tree/master/examples/shardingsphere-proxy-example/shardingsphere-proxy-hint-example/src/main/resources/conf)

View File

@ -0,0 +1,86 @@
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.budo</groupId>
<artifactId>budo-sharding-proxy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<distributionManagement>
<snapshotRepository>
<id>budo-snapshot-repository</id>
<url>${budo-snapshot-repository-url}</url>
</snapshotRepository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<elasticsearch.version>2.4.5</elasticsearch.version>
<budo-snapshot-repository-url>https://repo.rdc.aliyun.com/repository/1726-snapshot-ZLxSbx/</budo-snapshot-repository-url>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-proxy-bootstrap</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.budo</groupId>
<artifactId>budo-support</artifactId>
<version>0.0.3-bs-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.budo</groupId>
<artifactId>budo-mongo-jdbc-driver</artifactId>
<version>0.0.2-mi-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.budo</groupId>
<artifactId>budo-jdbc-driver</artifactId>
<version>0.0.2-dr-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.4.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,137 @@
package org.budo.sharding.proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.shardingsphere.core.database.DatabaseTypes;
import org.apache.shardingsphere.core.execute.sql.execute.SQLExecuteCallback;
import org.apache.shardingsphere.core.rule.Authentication;
import org.apache.shardingsphere.core.rule.ProxyUser;
import org.apache.shardingsphere.shardingproxy.backend.communication.jdbc.recognizer.JDBCDriverURLRecognizerEngine;
import org.apache.shardingsphere.shardingproxy.backend.communication.jdbc.recognizer.spi.JDBCDriverURLRecognizer;
import org.apache.shardingsphere.shardingproxy.backend.schema.LogicSchemas;
import org.apache.shardingsphere.shardingproxy.config.yaml.YamlDataSourceParameter;
import org.apache.shardingsphere.shardingproxy.context.ShardingProxyContext;
import org.apache.shardingsphere.shardingproxy.frontend.bootstrap.ShardingProxy;
import org.apache.shardingsphere.spi.database.DataSourceMetaData;
import org.apache.shardingsphere.spi.database.DatabaseType;
import org.budo.jdbc.driver.JdbcUrl;
import org.budo.sharding.proxy.recognizer.BudoShardingJdbcUrlRecognizer;
import org.budo.sharding.proxy.schema.BudoShardingLogicSchema;
import org.budo.sharding.spi.database.BudoShardingDataSourceMetaData;
import org.budo.support.lang.util.ReflectUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* @author lmw
*/
@Getter
@Setter
@Accessors(fluent = true)
public class BudoShardingProxy {
private static final String[] URL_PREFIX = { "jdbc:mysql://", "jdbc:mongo://", "jdbc:mongodb://" };
// proxy 配置
private JdbcUrl proxy = new JdbcUrl(3388, "root", "");
// 目标地址信息
private JdbcUrl target = new JdbcUrl().setUsername("root");
public void start() {
assert null != this.proxy();
assert null != this.target();
// DBMeta信息
this.prepareDataSourceMetaData();
// 连接地址识别
this.prepareJdbcUrlRecognizer();
// 账号密码信息
this.initAuthentication();
// 逻辑库信息
this.initLogicSchema();
// 启动 Proxy
ShardingProxy shardingProxy = ShardingProxy.getInstance();
shardingProxy.start(this.proxy().getPort());
}
/**
* 绕过本来的加载路径,直接反射加入到缓存中,供后续使用
*/
private void prepareJdbcUrlRecognizer() {
Object URL_RECOGNIZERS = ReflectUtil.getFieldValue(JDBCDriverURLRecognizerEngine.class, "JDBC_DRIVER_URL_RECOGNIZERS");
Collection<JDBCDriverURLRecognizer> jdbcDriverURLRecognizers = (Collection) URL_RECOGNIZERS;
BudoShardingJdbcUrlRecognizer jdbcUrlRecognizer = new BudoShardingJdbcUrlRecognizer(URL_PREFIX, this.target().getDriver());
jdbcDriverURLRecognizers.add(jdbcUrlRecognizer);
}
/**
* 绕过本来的加载路径,直接反射加入到缓存中,供后续使用
*/
private void prepareDataSourceMetaData() {
Object METADATA = ReflectUtil.getFieldValue(SQLExecuteCallback.class, "CACHED_DATASOURCE_METADATA");
Map<String, DataSourceMetaData> cachedDatasourceMetadata = (Map) METADATA;
BudoShardingDataSourceMetaData dataSourceMetaData = new BudoShardingDataSourceMetaData(this.target().getUrl(), URL_PREFIX);
cachedDatasourceMetadata.put(this.target().getUrl(), dataSourceMetaData);
}
private void initAuthentication() {
String username = this.proxy().getUsername();
String password = this.proxy().getPassword();
ShardingProxyContext shardingProxyContext = ShardingProxyContext.getInstance();
Authentication authentication = new Authentication();
ArrayList<String> authorizedSchemas = new ArrayList<String>();
authentication.getUsers().put(username, new ProxyUser(password, authorizedSchemas));
Properties props = new Properties();
shardingProxyContext.init(authentication, props);
}
private void initLogicSchema() {
LogicSchemas logicSchemas = LogicSchemas.getInstance();
// set databaseType MySQL
DatabaseType databaseType = DatabaseTypes.getActualDatabaseType("MySQL"); // MySQL
ReflectUtil.setFieldValue(logicSchemas, "databaseType", databaseType);
String schema = null != this.proxy().getCatalog() //
? this.proxy().getCatalog() //
: JdbcUrl.parse(this.target().getUrl(), URL_PREFIX).getCatalog();
Map<String, YamlDataSourceParameter> dataSources = this.dataSourceMap();
BudoShardingLogicSchema logicSchema = new BudoShardingLogicSchema(schema, dataSources);
logicSchemas.getLogicSchemas().put(schema, logicSchema);
}
private Map<String, YamlDataSourceParameter> dataSourceMap() {
String username = this.target().getUsername();
assert null != username;
String password = this.target().getPassword();
String url = this.target().getUrl();
String catalog = this.target().getCatalog();
YamlDataSourceParameter dataSourceParameter = new YamlDataSourceParameter();
dataSourceParameter.setUrl(url);
dataSourceParameter.setUsername(username); // 目标数据库的连接
dataSourceParameter.setPassword(password);
Map<String, YamlDataSourceParameter> dataSources = new HashMap<String, YamlDataSourceParameter>();
dataSources.put(catalog, dataSourceParameter);
return dataSources;
}
}

View File

@ -0,0 +1,30 @@
package org.budo.sharding.proxy.recognizer;
import java.util.Collection;
import org.apache.shardingsphere.shardingproxy.backend.communication.jdbc.recognizer.spi.JDBCDriverURLRecognizer;
import org.budo.support.lang.util.ListUtil;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* @author lmw
*/
@Getter
@NoArgsConstructor
public class BudoShardingJdbcUrlRecognizer implements JDBCDriverURLRecognizer {
private Collection<String> URLPrefixes;
private String driverClassName;
public BudoShardingJdbcUrlRecognizer(String[] urlPrefix, String driverClassName) {
this.URLPrefixes = ListUtil.toStringList(urlPrefix);
this.driverClassName = driverClassName;
}
@Override
public String getDatabaseType() {
throw new RuntimeException("#30 this=" + this);
}
}

View File

@ -0,0 +1,37 @@
package org.budo.sharding.proxy.schema;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.core.metadata.ShardingSphereMetaData;
import org.apache.shardingsphere.core.metadata.datasource.DataSourceMetas;
import org.apache.shardingsphere.core.metadata.table.TableMetas;
import org.apache.shardingsphere.core.rule.ShardingRule;
import org.apache.shardingsphere.shardingproxy.backend.schema.LogicSchema;
import org.apache.shardingsphere.shardingproxy.config.yaml.YamlDataSourceParameter;
import lombok.Getter;
/**
* @author lmw
*/
@Getter
public class BudoShardingLogicSchema extends LogicSchema {
private ShardingSphereMetaData metaData;
private ShardingRule shardingRule;
public BudoShardingLogicSchema(String name, Map<String, YamlDataSourceParameter> dataSources) {
super(name, dataSources);
DataSourceMetas dataSourceMetas = null;
TableMetas tableMetas = new TableMetas(Collections.EMPTY_MAP);
this.metaData = new ShardingSphereMetaData(dataSourceMetas, tableMetas);
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
Collection<String> dataSourceNames = Collections.singleton(name);
this.shardingRule = new ShardingRule(shardingRuleConfig, dataSourceNames);
}
}

View File

@ -0,0 +1,40 @@
package org.budo.sharding.spi.database;
import org.apache.shardingsphere.spi.database.DataSourceMetaData;
import org.budo.jdbc.driver.JdbcUrl;
/**
* @author lmw
* @see org.apache.shardingsphere.core.metadata.datasource.dialect.MySQLDataSourceMetaData
*/
public class BudoShardingDataSourceMetaData implements DataSourceMetaData {
private JdbcUrl jdbcUrl;
public BudoShardingDataSourceMetaData(String url, String[] urlPrefix, Integer defaultPort) {
this.jdbcUrl = JdbcUrl.parse(url, urlPrefix, defaultPort);
}
public BudoShardingDataSourceMetaData(String url, String[] urlPrefix) {
this.jdbcUrl = JdbcUrl.parse(url, urlPrefix, null);
}
@Override
public String getHostName() {
return this.jdbcUrl.getHost();
}
@Override
public int getPort() {
return this.jdbcUrl.getPort();
}
@Override
public String getCatalog() {
throw new RuntimeException("#33 this=" + this);
}
@Override
public String getSchema() {
throw new RuntimeException("#38 this=" + this);
}
}

View File

@ -0,0 +1,21 @@
package org.budo.jdbc.sharding.proxy;
import org.budo.mongo.jdbc.driver.BudoMongoJdbcDriver;
import org.budo.sharding.proxy.BudoShardingProxy;
/**
* @author lmw
*/
public class BudoShardingProxySample {
private static final String URL = "jdbc:mongo://192.168.4.32:27017/taobao";
public static void main(String[] args) {
BudoShardingProxy budoShardingProxy = new BudoShardingProxy();
budoShardingProxy.target() //
.setUrl(URL) //
.setDriver(BudoMongoJdbcDriver.class.getName());
budoShardingProxy.start();
}
}

View File

@ -24,6 +24,6 @@
<module>budo-mongo-jdbc-driver</module>
<module>budo-redis-jdbc-driver</module>
<module>budo-solr-jdbc-driver</module>
<module>budo-jdbc-sharding-proxy</module>
<module>budo-sharding-proxy</module>
</modules>
</project>