From eca308e06fe2c172871f57d17837cb85035d8329 Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Mon, 30 Dec 2024 14:02:26 +0800 Subject: [PATCH] ShardingConfig --- pom.xml | 55 ++++- src/main/java/com/sqx/SqxApplication.java | 43 ++-- src/main/java/com/sqx/config/RedisConfig.java | 7 + .../java/com/sqx/config/ShardingConfig.java | 153 ++++++++++++++ ...ataSourcePoolMetricsAutoConfiguration.java | 67 ++++++ .../java/com/sqx/config/SwaggerConfig.java | 143 +++++++------ .../sqx/datasource/annotation/DataSource.java | 14 -- .../datasource/aspect/DataSourceAspect.java | 61 ------ .../config/DynamicContextHolder.java | 47 ----- .../datasource/config/DynamicDataSource.java | 15 -- .../config/DynamicDataSourceConfig.java | 53 ----- .../config/DynamicDataSourceFactory.java | 44 ---- .../properties/DataSourceProperties.java | 192 ------------------ .../DynamicDataSourceProperties.java | 22 -- .../app/controller/app/AppController.java | 2 +- .../controller/app/AppCommonController.java | 2 +- .../com/sqx/sharding/MasterSlaveRules.java | 22 ++ .../com/sqx/sharding/ShardingDataBase.java | 61 ++++++ src/main/resources/application-local.yml | 61 ++++++ src/main/resources/application.properties | 1 + src/main/resources/application.yml | 10 +- 21 files changed, 542 insertions(+), 533 deletions(-) create mode 100644 src/main/java/com/sqx/config/ShardingConfig.java create mode 100644 src/main/java/com/sqx/config/ShardingDataSourcePoolMetricsAutoConfiguration.java delete mode 100644 src/main/java/com/sqx/datasource/annotation/DataSource.java delete mode 100644 src/main/java/com/sqx/datasource/aspect/DataSourceAspect.java delete mode 100644 src/main/java/com/sqx/datasource/config/DynamicContextHolder.java delete mode 100644 src/main/java/com/sqx/datasource/config/DynamicDataSource.java delete mode 100644 src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java delete mode 100644 src/main/java/com/sqx/datasource/config/DynamicDataSourceFactory.java delete mode 100644 src/main/java/com/sqx/datasource/properties/DataSourceProperties.java delete mode 100644 src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java create mode 100644 src/main/java/com/sqx/sharding/MasterSlaveRules.java create mode 100644 src/main/java/com/sqx/sharding/ShardingDataBase.java create mode 100644 src/main/resources/application-local.yml create mode 100644 src/main/resources/application.properties diff --git a/pom.xml b/pom.xml index b22e84e9..31ec0b85 100644 --- a/pom.xml +++ b/pom.xml @@ -35,12 +35,14 @@ 7.2.23 3.4.0 4.4 - 2.7.0 + + 2.9.2 2.9.9 2.8.5 1.2.83 4.6.10 1.18.4 + 4.1.1 + + com.baomidou + dynamic-datasource-spring-boot-starter + 4.1.3 + + mysql mysql-connector-java @@ -257,6 +278,23 @@ com.oracle ojdbc6 ${oracle.version} + + + + org.apache.shardingsphere + sharding-core-api + ${shardingsphere.version} + compile + + + org.apache.shardingsphere + sharding-jdbc-core + ${shardingsphere.version} + compile + + + org.springframework.boot + spring-boot-starter-actuator @@ -327,14 +365,25 @@ io.springfox - springfox-swagger2 + springfox-swagger-ui ${swagger.version} io.springfox - springfox-swagger-ui + springfox-swagger2 ${swagger.version} + + io.swagger + swagger-annotations + 1.5.22 + + + io.swagger + swagger-models + 1.5.22 + + com.qiniu qiniu-java-sdk diff --git a/src/main/java/com/sqx/SqxApplication.java b/src/main/java/com/sqx/SqxApplication.java index a3c22cfd..fada8ced 100644 --- a/src/main/java/com/sqx/SqxApplication.java +++ b/src/main/java/com/sqx/SqxApplication.java @@ -1,6 +1,7 @@ package com.sqx; import com.sqx.modules.pay.wuyou.WuyouPay; +import org.springframework.boot.Banner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @@ -18,25 +19,29 @@ import java.util.Map; public class SqxApplication { public static void main(String[] args) { - ConfigurableApplicationContext context = SpringApplication.run(SqxApplication.class, args); - context.getEnvironment().getPropertySources().forEach(source -> { - if (source.getName().contains("application-dev.yml") || source.getName().contains("application-prod.yml")) { - if (source.getSource() instanceof Map) { - ((Map) source.getSource()).forEach((key, value) -> { - System.out.println(key + ": " + value); - if ("pay.orderNotifyUrl".equals(key)) { - WuyouPay.setNotifyUrl(value.toString()); - } - if ("pay.extractNotifyUrl".equals(key)) { - WuyouPay.setExtractNotifyUrl(value.toString()); - } - if ("pay.h5BaseUrl".equals(key)) { - WuyouPay.setH5BaseUrl(value.toString()); - } - }); - } - } - }); + SpringApplication application = new SpringApplication(SqxApplication.class); + application.setBannerMode(Banner.Mode.OFF); + application.run(args); + +// ConfigurableApplicationContext context = SpringApplication.run(SqxApplication.class, args); +// context.getEnvironment().getPropertySources().forEach(source -> { +// if (source.getName().contains("application-dev.yml") || source.getName().contains("application-prod.yml")) { +// if (source.getSource() instanceof Map) { +// ((Map) source.getSource()).forEach((key, value) -> { +// System.out.println(key + ": " + value); +// if ("pay.orderNotifyUrl".equals(key)) { +// WuyouPay.setNotifyUrl(value.toString()); +// } +// if ("pay.extractNotifyUrl".equals(key)) { +// WuyouPay.setExtractNotifyUrl(value.toString()); +// } +// if ("pay.h5BaseUrl".equals(key)) { +// WuyouPay.setH5BaseUrl(value.toString()); +// } +// }); +// } +// } +// }); System.out.println("(♥◠‿◠)ノ゙ 短剧系统启动成功 ლ(´ڡ`ლ)゙ \n"+ " _ \n" + " | | \n" + diff --git a/src/main/java/com/sqx/config/RedisConfig.java b/src/main/java/com/sqx/config/RedisConfig.java index 6fddb78c..3188988c 100644 --- a/src/main/java/com/sqx/config/RedisConfig.java +++ b/src/main/java/com/sqx/config/RedisConfig.java @@ -1,5 +1,6 @@ package com.sqx.config; +import com.sqx.common.utils.RedisUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; @@ -70,4 +71,10 @@ public class RedisConfig { public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { return redisTemplate.opsForZSet(); } + + @Bean + public RedisUtils redisUtils() { + // 根据实际情况初始化RedisUtils实例,可能需要传入相关配置参数,如Redis连接信息等 + return new RedisUtils(); + } } diff --git a/src/main/java/com/sqx/config/ShardingConfig.java b/src/main/java/com/sqx/config/ShardingConfig.java new file mode 100644 index 00000000..12e0e2ed --- /dev/null +++ b/src/main/java/com/sqx/config/ShardingConfig.java @@ -0,0 +1,153 @@ +package com.sqx.config; + +import com.sqx.sharding.MasterSlaveRules; +import com.sqx.sharding.ShardingDataBase; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration; +import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration; +import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration; +import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; + + +/** + * sharding-jdbc 配置文件 + */ +@Slf4j +@Data +@Configuration +@ConfigurationProperties(prefix = "spring.shardingsphere") +public class ShardingConfig { + + /** + * 读取数据源信息 + */ + private Map datasource; + /** + * 读写分离的配置 + */ + private Map masterSlaveRules; + /** + * 显示sharding-jdbc的sql + */ + private String showSql; + + /** + * 中心库的节点 + */ + private String centerTablesDataNode; + + @Value("${center-tables}") + private String tableNamesAsString; + + /** + * 中心表,不进行分库操作 + */ +// @Value("${center-tables}") + private Set centerTables; + + @PostConstruct + public void init() { + // 使用换行符进行分割,然后去除空白字符,收集到Set集合中 + centerTables = Arrays.stream(tableNamesAsString.split(",")) + .map(String::trim) + .collect(Collectors.toSet()); + } + + + /** + * 配置sharding-jdbc数据源 + */ + @Bean + public DataSource dataSource() throws SQLException { + ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); + + // 配置数据库主从 + shardingRuleConfig.setMasterSlaveRuleConfigs(masterSlaveRuleConfigs()); + + // 配置表的切分策略 + shardingRuleConfig.setTableRuleConfigs(addTableRuleConfigs()); + + // 配置是否显示sql +// Properties props = new Properties(); +// props.put("sql.show", true); + + // 配置数据源 + Map dataSourceMap = getShardingDataBase(); + return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, null); +// return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, props); + } + + /** + * 配置 + */ + private Set addTableRuleConfigs() { + Set sets = new HashSet<>(); + for (String centerTable : centerTables) { + TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(centerTable, + String.format(centerTablesDataNode, centerTable)); + sets.add(tableRuleConfig); + } + +// // 定义区域表的分库规则 +// InlineShardingStrategyConfiguration databaseShardingStrategyConfig = new InlineShardingStrategyConfiguration( +// regionTablesShardingDatabaseColumn, regionTablesShardingDatabaseAlgorithm); +// for (String regionTable : regionTables) { +// TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable)); +// tableRuleConfig.setDatabaseShardingStrategyConfig(databaseShardingStrategyConfig); +// sets.add(tableRuleConfig); +// } + return sets; + } + + /** + * 配置数据源 + */ + private Map getShardingDataBase() { + String testQuery = "SELECT 1"; + Map map = new HashMap<>(); + datasource.forEach((datasourceName, shardingDataBase) -> { + HikariConfig config = new HikariConfig(); + config.setDriverClassName(shardingDataBase.getDriverClassName()); + config.setJdbcUrl(shardingDataBase.getJdbcUrl()); + config.setUsername(shardingDataBase.getUsername()); + config.setPassword(shardingDataBase.getPassword()); + config.setPoolName(datasourceName); + config.setMinimumIdle(shardingDataBase.getMinimumIdle()); + config.setMaximumPoolSize(shardingDataBase.getMaximumPoolSize()); + config.setIdleTimeout(shardingDataBase.getIdleTimeout()); + config.setMaxLifetime(shardingDataBase.getMaxLifetime()); + config.setConnectionTimeout(shardingDataBase.getConnectionTimeout()); + config.setConnectionTestQuery(testQuery); + map.put(datasourceName, new HikariDataSource(config)); + }); + return map; + } + + /** + * 配置读写分离 + */ + private Set masterSlaveRuleConfigs() { + Set sets = new HashSet<>(); + masterSlaveRules.forEach((databaseName, masterSlaveRules) -> { + MasterSlaveRuleConfiguration masterSlaveRuleConfig = new MasterSlaveRuleConfiguration(databaseName, + masterSlaveRules.getMasterDataSourceName(), masterSlaveRules.getSlaveDataSourceNames()); + System.out.println("写入"+masterSlaveRules.getMasterDataSourceName()); + System.out.println("读出"+masterSlaveRules.getSlaveDataSourceNames()); + sets.add(masterSlaveRuleConfig); + }); + return sets; + } +} \ No newline at end of file diff --git a/src/main/java/com/sqx/config/ShardingDataSourcePoolMetricsAutoConfiguration.java b/src/main/java/com/sqx/config/ShardingDataSourcePoolMetricsAutoConfiguration.java new file mode 100644 index 00000000..c3454b5a --- /dev/null +++ b/src/main/java/com/sqx/config/ShardingDataSourcePoolMetricsAutoConfiguration.java @@ -0,0 +1,67 @@ +package com.sqx.config; + +import com.zaxxer.hikari.HikariDataSource; +import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory; +import io.micrometer.core.instrument.MeterRegistry; +import lombok.extern.slf4j.Slf4j; +import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.jdbc.DataSourceUnwrapper; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; +import java.util.Collection; + +/** + * @author wxkj0012 + */ +@Configuration(proxyBeanMethods = false) +@AutoConfigureAfter({MetricsAutoConfiguration.class, DataSourceAutoConfiguration.class, + SimpleMetricsExportAutoConfiguration.class}) +@ConditionalOnClass({DataSource.class, MeterRegistry.class}) +@ConditionalOnBean({DataSource.class, MeterRegistry.class}) +@Slf4j +public class ShardingDataSourcePoolMetricsAutoConfiguration { + + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ShardingDataSource.class, HikariDataSource.class}) + static class ShardingDataSourceMetricsConfiguration { + + private final MeterRegistry registry; + + ShardingDataSourceMetricsConfiguration(MeterRegistry registry) { + this.registry = registry; + } + + @Autowired + void bindMetricsRegistryToHikariDataSources(Collection dataSources) { + for (DataSource dataSource : dataSources) { + ShardingDataSource shardingDataSource = DataSourceUnwrapper.unwrap(dataSource, ShardingDataSource.class); + Collection shardDataSources = shardingDataSource.getDataSourceMap().values(); + for (DataSource ds : shardDataSources) { + HikariDataSource hikariDataSource = DataSourceUnwrapper.unwrap(ds, HikariDataSource.class); + if (hikariDataSource != null) { + bindMetricsRegistryToHikariDataSource(hikariDataSource); + } + } + } + } + + private void bindMetricsRegistryToHikariDataSource(HikariDataSource hikari) { + if (hikari.getMetricRegistry() == null && hikari.getMetricsTrackerFactory() == null) { + try { + hikari.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(this.registry)); + } catch (Exception ex) { + log.warn("Failed to bind Hikari metrics: {}}", ex.getMessage()); + } + } + } + + } +} \ No newline at end of file diff --git a/src/main/java/com/sqx/config/SwaggerConfig.java b/src/main/java/com/sqx/config/SwaggerConfig.java index 8cf4bfee..8f991bfa 100644 --- a/src/main/java/com/sqx/config/SwaggerConfig.java +++ b/src/main/java/com/sqx/config/SwaggerConfig.java @@ -1,58 +1,85 @@ -package com.sqx.config; - -import io.swagger.annotations.ApiOperation; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiKey; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import java.util.List; - -import static com.google.common.collect.Lists.newArrayList; - -@Configuration -@EnableSwagger2 -public class SwaggerConfig implements WebMvcConfigurer { - - @Value("${swagger.enabled}") - private boolean enabled; - - @Bean - public Docket createRestApi() { - return new Docket(DocumentationType.SWAGGER_2) - .enable(enabled) - .apiInfo(apiInfo()) - .select() - //加了ApiOperation注解的类,才生成接口文档 - .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) - //包下的类,才生成接口文档 - //.apis(RequestHandlerSelectors.basePackage("com.sqx.controller")) - .paths(PathSelectors.any()) - .build() - .securitySchemes(security()); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title("") - .description("sqx-fast文档") - .termsOfServiceUrl("") - .version("3.0.0") - .build(); - } - - private List security() { - return newArrayList( - new ApiKey("token", "token", "header") - ); - } - -} \ No newline at end of file +//package com.sqx.config; +// +//import io.swagger.annotations.Api; +//import io.swagger.annotations.ApiOperation; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.context.annotation.Profile; +//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +//import springfox.documentation.builders.ApiInfoBuilder; +//import springfox.documentation.builders.PathSelectors; +//import springfox.documentation.builders.RequestHandlerSelectors; +//import springfox.documentation.service.ApiInfo; +//import springfox.documentation.service.ApiKey; +//import springfox.documentation.spi.DocumentationType; +//import springfox.documentation.spring.web.plugins.Docket; +//import springfox.documentation.swagger2.annotations.EnableSwagger2; +// +//import java.util.List; +// +//import static com.google.common.collect.Lists.newArrayList; +// +////@Configuration +////@EnableSwagger2 +////public class SwaggerConfig implements WebMvcConfigurer { +//// +//// @Value("${swagger.enabled}") +//// private boolean enabled; +//// +//// @Bean +//// public Docket createRestApi() { +//// return new Docket(DocumentationType.SWAGGER_2) +//// .enable(enabled) +//// .apiInfo(apiInfo()) +//// .select() +//// //加了ApiOperation注解的类,才生成接口文档 +//// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) +//// //包下的类,才生成接口文档 +//// //.apis(RequestHandlerSelectors.basePackage("com.sqx.controller")) +//// .paths(PathSelectors.any()) +//// .build() +//// .securitySchemes(security()); +//// } +//// +//// private ApiInfo apiInfo() { +//// return new ApiInfoBuilder() +//// .title("") +//// .description("sqx-fast文档") +//// .termsOfServiceUrl("") +//// .version("3.0.0") +//// .build(); +//// } +//// +//// private List security() { +//// return newArrayList( +//// new ApiKey("token", "token", "header") +//// ); +//// } +//// +////} +// +//@Configuration +//@EnableSwagger2 +//@Profile({"local", "dev"}) +//public class SwaggerConfig { +// +// @Bean +// public Docket api() { +// return new Docket(DocumentationType.SWAGGER_2) +// .apiInfo(apiInfo()) +// .select() +// .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) +// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) +// .paths(PathSelectors.any()) +// .build(); +// } +// +// private ApiInfo apiInfo() { +// return new ApiInfoBuilder() +// .title("悠车位后台API接口文档") +// .description("悠车位服务端后台API接口文档") +// .version("1.0") +// .build(); +// } +//} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/annotation/DataSource.java b/src/main/java/com/sqx/datasource/annotation/DataSource.java deleted file mode 100644 index 082da71b..00000000 --- a/src/main/java/com/sqx/datasource/annotation/DataSource.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.sqx.datasource.annotation; - -import java.lang.annotation.*; - -/** - * 多数据源注解 - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -public @interface DataSource { - String value() default ""; -} diff --git a/src/main/java/com/sqx/datasource/aspect/DataSourceAspect.java b/src/main/java/com/sqx/datasource/aspect/DataSourceAspect.java deleted file mode 100644 index b3c5d0ac..00000000 --- a/src/main/java/com/sqx/datasource/aspect/DataSourceAspect.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.sqx.datasource.aspect; - - -import com.sqx.datasource.annotation.DataSource; -import com.sqx.datasource.config.DynamicContextHolder; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.aspectj.lang.reflect.MethodSignature; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import java.lang.reflect.Method; - -/** - * 多数据源,切面处理类 - */ -@Aspect -@Component -@Order(Ordered.HIGHEST_PRECEDENCE) -public class DataSourceAspect { - protected Logger logger = LoggerFactory.getLogger(getClass()); - - @Pointcut("@annotation(com.sqx.datasource.annotation.DataSource) " + - "|| @within(com.sqx.datasource.annotation.DataSource)") - public void dataSourcePointCut() { - - } - - @Around("dataSourcePointCut()") - public Object around(ProceedingJoinPoint point) throws Throwable { - MethodSignature signature = (MethodSignature) point.getSignature(); - Class targetClass = point.getTarget().getClass(); - Method method = signature.getMethod(); - - DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class); - DataSource methodDataSource = method.getAnnotation(DataSource.class); - if(targetDataSource != null || methodDataSource != null){ - String value; - if(methodDataSource != null){ - value = methodDataSource.value(); - }else { - value = targetDataSource.value(); - } - - DynamicContextHolder.push(value); - logger.debug("set datasource is {}", value); - } - - try { - return point.proceed(); - } finally { - DynamicContextHolder.poll(); - logger.debug("clean datasource"); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/config/DynamicContextHolder.java b/src/main/java/com/sqx/datasource/config/DynamicContextHolder.java deleted file mode 100644 index f059bf76..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicContextHolder.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.sqx.datasource.config; - -import java.util.ArrayDeque; -import java.util.Deque; - -/** - * 多数据源上下文 - */ -public class DynamicContextHolder { - @SuppressWarnings("unchecked") - private static final ThreadLocal> CONTEXT_HOLDER = new ThreadLocal() { - @Override - protected Object initialValue() { - return new ArrayDeque(); - } - }; - - /** - * 获得当前线程数据源 - * - * @return 数据源名称 - */ - public static String peek() { - return CONTEXT_HOLDER.get().peek(); - } - - /** - * 设置当前线程数据源 - * - * @param dataSource 数据源名称 - */ - public static void push(String dataSource) { - CONTEXT_HOLDER.get().push(dataSource); - } - - /** - * 清空当前线程数据源 - */ - public static void poll() { - Deque deque = CONTEXT_HOLDER.get(); - deque.poll(); - if (deque.isEmpty()) { - CONTEXT_HOLDER.remove(); - } - } - -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/config/DynamicDataSource.java b/src/main/java/com/sqx/datasource/config/DynamicDataSource.java deleted file mode 100644 index 4374032b..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicDataSource.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sqx.datasource.config; - -import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; - -/** - * 多数据源 - */ -public class DynamicDataSource extends AbstractRoutingDataSource { - - @Override - protected Object determineCurrentLookupKey() { - return DynamicContextHolder.peek(); - } - -} diff --git a/src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java b/src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java deleted file mode 100644 index 9c1033fd..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicDataSourceConfig.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.sqx.datasource.config; - -import com.alibaba.druid.pool.DruidDataSource; -import com.sqx.datasource.properties.DataSourceProperties; -import com.sqx.datasource.properties.DynamicDataSourceProperties; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.HashMap; -import java.util.Map; - -/** - * 配置多数据源 - */ -@Configuration -@EnableConfigurationProperties(DynamicDataSourceProperties.class) -public class DynamicDataSourceConfig { - @Autowired - private DynamicDataSourceProperties properties; - - @Bean - @ConfigurationProperties(prefix = "spring.datasource.druid") - public DataSourceProperties dataSourceProperties() { - return new DataSourceProperties(); - } - - @Bean - public DynamicDataSource dynamicDataSource(DataSourceProperties dataSourceProperties) { - DynamicDataSource dynamicDataSource = new DynamicDataSource(); - dynamicDataSource.setTargetDataSources(getDynamicDataSource()); - - //默认数据源 - DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperties); - dynamicDataSource.setDefaultTargetDataSource(defaultDataSource); - - return dynamicDataSource; - } - - private Map getDynamicDataSource(){ - Map dataSourcePropertiesMap = properties.getDatasource(); - Map targetDataSources = new HashMap<>(dataSourcePropertiesMap.size()); - dataSourcePropertiesMap.forEach((k, v) -> { - DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v); - targetDataSources.put(k, druidDataSource); - }); - - return targetDataSources; - } - -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/config/DynamicDataSourceFactory.java b/src/main/java/com/sqx/datasource/config/DynamicDataSourceFactory.java deleted file mode 100644 index b506b40c..00000000 --- a/src/main/java/com/sqx/datasource/config/DynamicDataSourceFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.sqx.datasource.config; - -import com.alibaba.druid.pool.DruidDataSource; -import com.sqx.datasource.properties.DataSourceProperties; - -import java.sql.SQLException; - -/** - * DruidDataSource - * - */ -public class DynamicDataSourceFactory { - - public static DruidDataSource buildDruidDataSource(DataSourceProperties properties) { - DruidDataSource druidDataSource = new DruidDataSource(); - druidDataSource.setDriverClassName(properties.getDriverClassName()); - druidDataSource.setUrl(properties.getUrl()); - druidDataSource.setUsername(properties.getUsername()); - druidDataSource.setPassword(properties.getPassword()); - - druidDataSource.setInitialSize(properties.getInitialSize()); - druidDataSource.setMaxActive(properties.getMaxActive()); - druidDataSource.setMinIdle(properties.getMinIdle()); - druidDataSource.setMaxWait(properties.getMaxWait()); - druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis()); - druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis()); - druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis()); - druidDataSource.setValidationQuery(properties.getValidationQuery()); - druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout()); - druidDataSource.setTestOnBorrow(properties.isTestOnBorrow()); - druidDataSource.setTestOnReturn(properties.isTestOnReturn()); - druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements()); - druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements()); - druidDataSource.setSharePreparedStatements(properties.isSharePreparedStatements()); - - try { - druidDataSource.setFilters(properties.getFilters()); - druidDataSource.init(); - } catch (SQLException e) { - e.printStackTrace(); - } - return druidDataSource; - } -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/properties/DataSourceProperties.java b/src/main/java/com/sqx/datasource/properties/DataSourceProperties.java deleted file mode 100644 index 0cc4fc44..00000000 --- a/src/main/java/com/sqx/datasource/properties/DataSourceProperties.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.sqx.datasource.properties; - -/** - * 多数据源属性 - * - */ -public class DataSourceProperties { - private String driverClassName; - private String url; - private String username; - private String password; - - /** - * Druid默认参数 - */ - private int initialSize = 2; - private int maxActive = 10; - private int minIdle = -1; - private long maxWait = 60 * 1000L; - private long timeBetweenEvictionRunsMillis = 60 * 1000L; - private long minEvictableIdleTimeMillis = 1000L * 60L * 30L; - private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7; - private String validationQuery = "select 1"; - private int validationQueryTimeout = -1; - private boolean testOnBorrow = false; - private boolean testOnReturn = false; - private boolean testWhileIdle = true; - private boolean poolPreparedStatements = false; - private int maxOpenPreparedStatements = -1; - private boolean sharePreparedStatements = false; - private String filters = "stat,wall"; - - public String getDriverClassName() { - return driverClassName; - } - - public void setDriverClassName(String driverClassName) { - this.driverClassName = driverClassName; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public int getInitialSize() { - return initialSize; - } - - public void setInitialSize(int initialSize) { - this.initialSize = initialSize; - } - - public int getMaxActive() { - return maxActive; - } - - public void setMaxActive(int maxActive) { - this.maxActive = maxActive; - } - - public int getMinIdle() { - return minIdle; - } - - public void setMinIdle(int minIdle) { - this.minIdle = minIdle; - } - - public long getMaxWait() { - return maxWait; - } - - public void setMaxWait(long maxWait) { - this.maxWait = maxWait; - } - - public long getTimeBetweenEvictionRunsMillis() { - return timeBetweenEvictionRunsMillis; - } - - public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) { - this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; - } - - public long getMinEvictableIdleTimeMillis() { - return minEvictableIdleTimeMillis; - } - - public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { - this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; - } - - public long getMaxEvictableIdleTimeMillis() { - return maxEvictableIdleTimeMillis; - } - - public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) { - this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis; - } - - public String getValidationQuery() { - return validationQuery; - } - - public void setValidationQuery(String validationQuery) { - this.validationQuery = validationQuery; - } - - public int getValidationQueryTimeout() { - return validationQueryTimeout; - } - - public void setValidationQueryTimeout(int validationQueryTimeout) { - this.validationQueryTimeout = validationQueryTimeout; - } - - public boolean isTestOnBorrow() { - return testOnBorrow; - } - - public void setTestOnBorrow(boolean testOnBorrow) { - this.testOnBorrow = testOnBorrow; - } - - public boolean isTestOnReturn() { - return testOnReturn; - } - - public void setTestOnReturn(boolean testOnReturn) { - this.testOnReturn = testOnReturn; - } - - public boolean isTestWhileIdle() { - return testWhileIdle; - } - - public void setTestWhileIdle(boolean testWhileIdle) { - this.testWhileIdle = testWhileIdle; - } - - public boolean isPoolPreparedStatements() { - return poolPreparedStatements; - } - - public void setPoolPreparedStatements(boolean poolPreparedStatements) { - this.poolPreparedStatements = poolPreparedStatements; - } - - public int getMaxOpenPreparedStatements() { - return maxOpenPreparedStatements; - } - - public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) { - this.maxOpenPreparedStatements = maxOpenPreparedStatements; - } - - public boolean isSharePreparedStatements() { - return sharePreparedStatements; - } - - public void setSharePreparedStatements(boolean sharePreparedStatements) { - this.sharePreparedStatements = sharePreparedStatements; - } - - public String getFilters() { - return filters; - } - - public void setFilters(String filters) { - this.filters = filters; - } -} \ No newline at end of file diff --git a/src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java b/src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java deleted file mode 100644 index ebd2a269..00000000 --- a/src/main/java/com/sqx/datasource/properties/DynamicDataSourceProperties.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.sqx.datasource.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * 多数据源属性 - */ -@ConfigurationProperties(prefix = "dynamic") -public class DynamicDataSourceProperties { - private Map datasource = new LinkedHashMap<>(); - - public Map getDatasource() { - return datasource; - } - - public void setDatasource(Map datasource) { - this.datasource = datasource; - } -} diff --git a/src/main/java/com/sqx/modules/app/controller/app/AppController.java b/src/main/java/com/sqx/modules/app/controller/app/AppController.java index 56121135..c55a5cb6 100644 --- a/src/main/java/com/sqx/modules/app/controller/app/AppController.java +++ b/src/main/java/com/sqx/modules/app/controller/app/AppController.java @@ -107,8 +107,8 @@ public class AppController { userEntity.setUserId(userId); old.setZhiFuBao(userEntity.getZhiFuBao()); old.setZhiFuBaoName(userEntity.getZhiFuBaoName()); + boolean bool = userService.updateById(userEntity); // 去除首绑支付宝奖励 -// boolean bool = userService.updateById(userEntity); // if (bool && isFirstBind) { // userService.firstBindAwardsMoney(old); // } diff --git a/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java b/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java index 55c3a3dd..774f6966 100644 --- a/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java +++ b/src/main/java/com/sqx/modules/common/controller/app/AppCommonController.java @@ -47,7 +47,7 @@ public class AppCommonController { " 20后台管理平台域名配置\n" + " 22拼多多优惠券地址") @ResponseBody - @Login +// @Login public Result getCommonList(@PathVariable Integer type) { return commonService.findByType(type); } diff --git a/src/main/java/com/sqx/sharding/MasterSlaveRules.java b/src/main/java/com/sqx/sharding/MasterSlaveRules.java new file mode 100644 index 00000000..064773e0 --- /dev/null +++ b/src/main/java/com/sqx/sharding/MasterSlaveRules.java @@ -0,0 +1,22 @@ +package com.sqx.sharding; + +import lombok.Data; + +import java.util.List; + +/** + * 读写分离配置 + */ +@Data +public class MasterSlaveRules { + + /** + * 写库 + */ + private String masterDataSourceName; + + /** + * 读库 + */ + private List slaveDataSourceNames; +} \ No newline at end of file diff --git a/src/main/java/com/sqx/sharding/ShardingDataBase.java b/src/main/java/com/sqx/sharding/ShardingDataBase.java new file mode 100644 index 00000000..ccf6f58c --- /dev/null +++ b/src/main/java/com/sqx/sharding/ShardingDataBase.java @@ -0,0 +1,61 @@ +package com.sqx.sharding; + +import lombok.Data; + +/** + * 用于注入sharding-jdbc的值 + */ +@Data +public class ShardingDataBase { + + /** + * 连接池 + */ + private String type; + + /** + * 驱动名称 + */ + private String driverClassName; + + /** + * 数据库地址 + */ + private String jdbcUrl; + + /** + * 数据库用户名 + */ + private String username; + + /** + * 数据库密码 + */ + private String password; + + /** + * 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size + */ + private int minimumIdle; + + /** + * 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值 + */ + private int maximumPoolSize; + + /** + * 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。 + */ + private int idleTimeout; + + /** + * 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短 + */ + private int maxLifetime; + + /** + * 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒 + */ + private int connectionTimeout; + +} \ No newline at end of file diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml new file mode 100644 index 00000000..2c965598 --- /dev/null +++ b/src/main/resources/application-local.yml @@ -0,0 +1,61 @@ +# 数据源的一些配置 +driver-class-name: com.mysql.cj.jdbc.Driver +# 最小空闲连接,默认值10,小于0或大于maximum-pool-size,都会重置为maximum-pool-size +minimum-idle: 5 +# 最大连接数,小于等于0会被重置为默认值10;大于零小于1会被重置为minimum-idle的值 +maximum-pool-size: 15 +# 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。 +idle-timeout: 30000 +# 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短 +max-lifetime: 30000 +# 连接超时时间:毫秒,小于250毫秒,否则被重置为默认值30秒 +connection-timeout: 30000 + +spring: + # sharding-jdbc 配置 + shardingsphere: + center-tables-data-node: duanju.%s + # 显示sharding-jdbc改写的sql语句 + show-sql: true + # 数据源名称 + datasource: + # 数据源配置begin + master-0: +# slave-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: video_user + password: VideoUser@1 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + slave-0: +# master-0: + driver-class-name: ${driver-class-name} + jdbc-url: jdbc:mysql://47.122.26.160:3306/duanju?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=CTT + username: root + password: 0fd6497c308ccfa8 + minimum-idle: ${minimum-idle} + maximum-pool-size: ${maximum-pool-size} + idle-timeout: ${idle-timeout} + max-lifetime: ${max-lifetime} + connection-timeout: ${connection-timeout} + # 数据源配置end + + # 读写分离配置begin + master-slave-rules: + #数据源 + duanju: + master-data-source-name: master-0 + slave-data-source-names: slave-0 +# - master-0 +# - slave-0 + +swagger: + enabled: true +pay: + h5BaseUrl: https://video-h5.hnsiyao.cn/me/detail/detail?allId= + orderNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/notify + extractNotifyUrl: https://video.hnsiyao.cn/czg/app/wuyou/extractNotify diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..3621d08e --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ +center-tables=activity,app,banner,cash_out,comment_good,common_info,complet_award,coupon,coupon_user,course,course_classification,course_collect,course_comment,course_details,course_user,disc_spinning,disc_spinning_amount,disc_spinning_record,help_classify,help_word,invite,invite_award,invite_money,message_info,msg,orders,pay_classify,pay_details,qrtz_blob_triggers,qrtz_calendars,qrtz_cron_triggers,qrtz_fired_triggers,qrtz_job_details,qrtz_locks,qrtz_paused_trigger_grps,qrtz_scheduler_state,qrtz_simple_triggers,qrtz_simprop_triggers,qrtz_triggers,schedule_job,schedule_job_log,sdk_info,sdk_type,search,sys_captcha,sys_config,sys_dict,sys_log,sys_menu,sys_oss,sys_role,sys_role_menu,sys_user,sys_user_role,sys_user_token,task_center,task_center_record,task_center_reward,tb_user,uni_ad_callback_record,url_address,user_integral,user_integral_details,user_money,user_money_details,user_prize_exchange,user_sign_record,user_vip,vip_details \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3c9ca3c1..55267cae 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -20,7 +20,7 @@ spring: allow-bean-definition-overriding: true # 环境 dev|test|prod profiles: - active: dev + active: local # jackson时间格式化 jackson: time-zone: GMT+8 @@ -45,10 +45,14 @@ spring: min-idle: 5 # 连接池中的最小空闲连接 mvc: throw-exception-if-no-handler-found: true - pathmatch: - matching-strategy: ant_path_matcher +# pathmatch: +# matching-strategy: ant_path_matcher +management: + health: + db: + enabled: false #关闭数据库健康检查isV #mybatis mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml