参考工程地址:https://gitee.com/proLeo/ray,分支dev-2.0,部分配置如下
3.1.0
2.0.0
1.1.22
4.1.0
com.alibaba.spring.boot
dubbo-spring-boot-starter
${dubbo.starter.version}
com.alibaba
druid-spring-boot-starter
${druid.starter.version}
com.baomidou
mybatis-plus-boot-starter
${mybatis-plus.version}
com.baomidou
mybatis-plus-generator
${mybatis-plus.version}
org.apache.shardingsphere
sharding-jdbc-spring-boot-starter
${shardingsphere.version}
org.apache.shardingsphere
sharding-transaction-xa-core
${shardingsphere.version}
org.apache.shardingsphere
sharding-transaction-base-seata-at
${shardingsphere.version}
spring:
datasource:
druid:
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
web-stat-filter:
enabled: true
url-pattern: "/*"
exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 1000
# 配置DruidStatViewServlet
stat-view-servlet:
enabled: true
url-pattern: "/druid/*"
# IP白名单(没有配置或者为空,则允许所有访问)
# allow: 127.0.0.1,192.168.46.120
# IP黑名单 (存在共同时,deny优先于allow)
# deny: 192.168.46.121
# 禁用HTML页面上的“Reset All”功能
reset-enable: false
# 登录名
login-username: admin
# 登录密码
login-password: 123456
dubbo:
application:
name: ray-iflow-rpc-service
registry: zookeeper://192.168.125.161:2183
protocol:
id: dubbo
name: dubbo
port: 20881
status: server
#sharding配置
shardingsphere:
dataSource:
names: master0,master1,master0-slave1,master0-slave2,master1-slave1
master0:
type: com.alibaba.druid.pool.DruidDataSource
#自定义的配置项,因为type为DruidDataSource,需要特别配置filters,否则shardingsphere注入的DruidDataSource不含filters,不能实现相关的监控功能
filters: com.alibaba.druid.filter.stat.StatFilter,com.alibaba.druid.wall.WallFilter,com.alibaba.druid.filter.logging.Log4j2Filter
url: jdbc:mysql://192.168.125.161:36005/iflow?autoReconnect=true&useUnicode=true&createDatabaseIfNotExist=true&characterEncoding=utf8&useSSL=false&serverTimezone=CTT
username: root
#使用了自定义的AES对称加密,启动时需要添加启动参数-Denc.key=${自定义的key},用ray-common中的AESUtil加密
#如果不需要去除enc:前缀即可
password: enc:jEhi6SfY38B7rIB9wrFZ1w==
driver-class-name: com.mysql.cj.jdbc.Driver
master0-slave1:
type: com.alibaba.druid.pool.DruidDataSource
filters: com.alibaba.druid.filter.stat.StatFilter,com.alibaba.druid.wall.WallFilter,com.alibaba.druid.filter.logging.Log4j2Filter
url: jdbc:mysql://192.168.125.161:36006/iflow?autoReconnect=true&useUnicode=true&createDatabaseIfNotExist=true&characterEncoding=utf8&useSSL=false&serverTimezone=CTT
username: root
password: enc:jEhi6SfY38B7rIB9wrFZ1w==
driver-class-name: com.mysql.cj.jdbc.Driver
master0-slave2:
type: com.alibaba.druid.pool.DruidDataSource
filters: com.alibaba.druid.filter.stat.StatFilter,com.alibaba.druid.wall.WallFilter,com.alibaba.druid.filter.logging.Log4j2Filter
url: jdbc:mysql://192.168.125.161:36007/iflow?autoReconnect=true&useUnicode=true&createDatabaseIfNotExist=true&characterEncoding=utf8&useSSL=false&serverTimezone=CTT
username: root
password: enc:jEhi6SfY38B7rIB9wrFZ1w==
driver-class-name: com.mysql.cj.jdbc.Driver
master1:
type: com.alibaba.druid.pool.DruidDataSource
filters: com.alibaba.druid.filter.stat.StatFilter,com.alibaba.druid.wall.WallFilter,com.alibaba.druid.filter.logging.Log4j2Filter
url: jdbc:mysql://192.168.125.161:36008/iflow?autoReconnect=true&useUnicode=true&createDatabaseIfNotExist=true&characterEncoding=utf8&useSSL=false&serverTimezone=CTT
username: root
password: enc:jEhi6SfY38B7rIB9wrFZ1w==
driver-class-name: com.mysql.cj.jdbc.Driver
master1-slave1:
type: com.alibaba.druid.pool.DruidDataSource
filters: com.alibaba.druid.filter.stat.StatFilter,com.alibaba.druid.wall.WallFilter,com.alibaba.druid.filter.logging.Log4j2Filter
url: jdbc:mysql://192.168.125.161:36009/iflow?autoReconnect=true&useUnicode=true&createDatabaseIfNotExist=true&characterEncoding=utf8&useSSL=false&serverTimezone=CTT
username: root
password: enc:jEhi6SfY38B7rIB9wrFZ1w==
driver-class-name: com.mysql.cj.jdbc.Driver
#分库分表
sharding:
tables:
operation:
#此处有坑,如果配置了master-slave-rules则需要用其中配置的数据源
#actual-data-nodes: master$->{0..1}.operation_$->{0..1}
#表规则
actual-data-nodes: db_master_$->{0..1}.operation_$->{0..1}
#分库策略
database-strategy:
inline:
sharding-column: assess_status
#和上面同样的坑,如果配置了master-slave-rules则需要用其中配置的数据源,
#但是io.shardingsphere的starter确可以直接取datasource中的数据源
algorithm-expression: db_master_$->{assess_status%2}
#分表策略
table-strategy:
inline:
sharding-column: id
algorithm-expression: operation_$->{id % 2}
# default-key-generator:
# type: SnowflakeShardingKeyGenerator
# column: id
master-slave-rules:
db_master_0:
name: m0s2
master-data-source-name: master0
slave-data-source-names: master0-slave1,master0-slave2
db_master_1:
name: m1s1
master-data-source-name: master1
slave-data-source-names: master1-slave1
props:
sql:
show: true
server:
tomcat:
uri-encoding: UTF-8
port: 8085
mybatis-plus:
datasource: dataSource
mapper-locations: classpath*:/mappers/**/**Mapper.xml
typeAliasesPackage: com.mrray.ray.iflow.dao.base.model
configuration:
cache-enabled: false
package com.mrray.ray.common.sharding;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.google.common.base.Preconditions;
import com.mrray.ray.common.SpringContextUtil;
import org.apache.shardingsphere.core.yaml.swapper.MasterSlaveRuleConfigurationYamlSwapper;
import org.apache.shardingsphere.core.yaml.swapper.ShardingRuleConfigurationYamlSwapper;
import org.apache.shardingsphere.core.yaml.swapper.impl.ShadowRuleConfigurationYamlSwapper;
import org.apache.shardingsphere.encrypt.yaml.swapper.EncryptRuleConfigurationYamlSwapper;
import org.apache.shardingsphere.shardingjdbc.api.EncryptDataSourceFactory;
import org.apache.shardingsphere.shardingjdbc.api.MasterSlaveDataSourceFactory;
import org.apache.shardingsphere.shardingjdbc.api.ShadowDataSourceFactory;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.shardingjdbc.spring.boot.common.SpringBootPropertiesConfigurationProperties;
import org.apache.shardingsphere.shardingjdbc.spring.boot.encrypt.EncryptRuleCondition;
import org.apache.shardingsphere.shardingjdbc.spring.boot.encrypt.SpringBootEncryptRuleConfigurationProperties;
import org.apache.shardingsphere.shardingjdbc.spring.boot.masterslave.MasterSlaveRuleCondition;
import org.apache.shardingsphere.shardingjdbc.spring.boot.masterslave.SpringBootMasterSlaveRuleConfigurationProperties;
import org.apache.shardingsphere.shardingjdbc.spring.boot.shadow.ShadowRuleCondition;
import org.apache.shardingsphere.shardingjdbc.spring.boot.shadow.SpringBootShadowRuleConfigurationProperties;
import org.apache.shardingsphere.shardingjdbc.spring.boot.sharding.ShardingRuleCondition;
import org.apache.shardingsphere.shardingjdbc.spring.boot.sharding.SpringBootShardingRuleConfigurationProperties;
import org.apache.shardingsphere.spring.boot.datasource.DataSourcePropertiesSetterHolder;
import org.apache.shardingsphere.spring.boot.util.DataSourceUtil;
import org.apache.shardingsphere.spring.boot.util.PropertyUtil;
import org.apache.shardingsphere.transaction.spring.ShardingTransactionTypeScanner;
import org.apache.shardingsphere.underlying.common.config.inline.InlineExpressionParser;
import org.apache.shardingsphere.underlying.common.exception.ShardingSphereException;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.jndi.JndiObjectFactoryBean;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 自定义shardingsphere配置,实际拷贝自原配置文件,只做少量改动
*
* @author lyc
**/
@Configuration
@ComponentScan({"org.apache.shardingsphere.spring.boot.converter"})
@EnableConfigurationProperties({SpringBootShardingRuleConfigurationProperties.class, SpringBootMasterSlaveRuleConfigurationProperties.class, SpringBootEncryptRuleConfigurationProperties.class, SpringBootPropertiesConfigurationProperties.class, SpringBootShadowRuleConfigurationProperties.class})
@ConditionalOnProperty(
prefix = "spring.shardingsphere",
name = {"enabled"},
havingValue = "true",
matchIfMissing = true
)
@AutoConfigureBefore({DruidDataSourceAutoConfigure.class, DataSourceAutoConfiguration.class})
public class MyShardingsphereConfig implements EnvironmentAware {
private final SpringBootShardingRuleConfigurationProperties shardingRule;
private final SpringBootMasterSlaveRuleConfigurationProperties masterSlaveRule;
private final SpringBootEncryptRuleConfigurationProperties encryptRule;
private final SpringBootShadowRuleConfigurationProperties shadowRule;
private final SpringBootPropertiesConfigurationProperties props;
private final Map dataSourceMap = new LinkedHashMap();
private static final String JNDI_NAME = "jndi-name";
private static final String DRUID_FILTER_PREFIX = "filters";
/**
* 配置属性自动填充
*
* @return
*/
@Bean
@ConditionalOnMissingBean(SpringContextUtil.class)
public SpringContextUtil springContextUtil() {
return new SpringContextUtil();
}
@Bean
@Conditional({ShardingRuleCondition.class})
public DataSource shardingDataSource() throws SQLException {
return ShardingDataSourceFactory.createDataSource(dataSourceMap, (new ShardingRuleConfigurationYamlSwapper()).swap(shardingRule), props.getProps());
}
@Bean
@Conditional({MasterSlaveRuleCondition.class})
public DataSource masterSlaveDataSource() throws SQLException {
return MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, (new MasterSlaveRuleConfigurationYamlSwapper()).swap(masterSlaveRule), props.getProps());
}
@Bean
@Conditional({EncryptRuleCondition.class})
public DataSource encryptDataSource() throws SQLException {
return EncryptDataSourceFactory.createDataSource((DataSource) dataSourceMap.values().iterator().next(), (new EncryptRuleConfigurationYamlSwapper()).swap(encryptRule), props.getProps());
}
@Bean
@Conditional({ShadowRuleCondition.class})
public DataSource shadowDataSource() throws SQLException {
return ShadowDataSourceFactory.createDataSource(dataSourceMap, (new ShadowRuleConfigurationYamlSwapper()).swap(shadowRule), props.getProps());
}
@Bean
public ShardingTransactionTypeScanner shardingTransactionTypeScanner() {
return new ShardingTransactionTypeScanner();
}
@Override
public final void setEnvironment(Environment environment) {
String prefix = "spring.shardingsphere.datasource.";
for (String dsName : getDataSourceNames(environment, prefix)) {
try {
dataSourceMap.put(dsName, getDataSource(environment, prefix, dsName));
} catch (ReflectiveOperationException reflectiveOperationException) {
throw new ShardingSphereException("Can't find datasource type!", reflectiveOperationException);
} catch (NamingException namingException) {
throw new ShardingSphereException("Can't find JNDI datasource!", namingException);
} catch (SQLException sqlException) {
throw new ShardingSphereException("set druidDatasource filters failed!", sqlException);
}
}
}
private List getDataSourceNames(Environment environment, String prefix) {
StandardEnvironment standardEnv = (StandardEnvironment) environment;
standardEnv.setIgnoreUnresolvableNestedPlaceholders(true);
return null == standardEnv.getProperty(prefix + "name") ? (new InlineExpressionParser(standardEnv.getProperty(prefix + "names"))).splitAndEvaluate() : Collections.singletonList(standardEnv.getProperty(prefix + "name"));
}
private DataSource getDataSource(Environment environment, String prefix, String dataSourceName) throws ReflectiveOperationException, NamingException, SQLException {
Map dataSourceProps = (Map) PropertyUtil.handle(environment, prefix + dataSourceName.trim(), Map.class);
Preconditions.checkState(!dataSourceProps.isEmpty(), "Wrong datasource properties!");
if (dataSourceProps.containsKey(JNDI_NAME)) {
return getJndiDataSource(dataSourceProps.get(JNDI_NAME).toString());
} else {
DataSource result = DataSourceUtil.getDataSource(dataSourceProps.get("type").toString(), dataSourceProps);
//*******适配druidDataSource,添加filter,否则不能实现sql,防火墙等监控功能!!!**************
if (result instanceof DruidDataSource) {
if (dataSourceProps.get(DRUID_FILTER_PREFIX) != null) {
((DruidDataSource) result).setFilters(dataSourceProps.get(DRUID_FILTER_PREFIX).toString());
}
}
DataSourcePropertiesSetterHolder.getDataSourcePropertiesSetterByType(dataSourceProps.get("type").toString()).ifPresent((dataSourcePropertiesSetter) -> {
dataSourcePropertiesSetter.propertiesSet(environment, prefix, dataSourceName, result);
});
return result;
}
}
private DataSource getJndiDataSource(String jndiName) throws NamingException {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setResourceRef(true);
bean.setJndiName(jndiName);
bean.setProxyInterface(DataSource.class);
bean.afterPropertiesSet();
return (DataSource) bean.getObject();
}
public MyShardingsphereConfig(SpringBootShardingRuleConfigurationProperties shardingRule, SpringBootMasterSlaveRuleConfigurationProperties masterSlaveRule, SpringBootEncryptRuleConfigurationProperties encryptRule, SpringBootShadowRuleConfigurationProperties shadowRule, SpringBootPropertiesConfigurationProperties props) {
this.shardingRule = shardingRule;
this.masterSlaveRule = masterSlaveRule;
this.encryptRule = encryptRule;
this.shadowRule = shadowRule;
this.props = props;
}
}