From 9eef32d9ea9fec80104c71f4a8761b420eae0c94 Mon Sep 17 00:00:00 2001 From: yangyang01000846 <15195822163@163.com> Date: Wed, 12 Nov 2025 13:41:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E4=BD=9C=E4=B8=9A?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=A1=B9=E7=9B=AE=E6=8F=90=E4=BA=A4=EF=BC=9B?= =?UTF-8?q?mdc=E6=97=A5=E5=BF=97=E8=BF=BD=E8=B8=AA=E6=8F=90=E6=95=88?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- capability/src/main/resources/logback.xml | 29 +++- common/pom.xml | 9 ++ .../mdc/FeignMdcRequestInterceptor.java | 19 +++ .../common/common/mdc/HttpFilterConfig.java | 15 ++ .../common/common/mdc/MdcTaskDecorator.java | 23 +++ .../sdm/common/common/mdc/TraceIdFilter.java | 62 ++++++++ .../com/sdm/common/utils/log/CoreLogger.java | 142 ++++++++++++++++++ data/src/main/resources/logback.xml | 28 +++- pom.xml | 1 + project/src/main/resources/logback.xml | 31 +++- submit/pom.xml | 141 +++++++++++++++++ .../com/sdm/submit/SubmitApplication.java | 19 +++ .../DecryptEnvironmentPostProcessor.java | 49 ++++++ .../com/sdm/submit/config/MinioConfig.java | 40 +++++ .../submit/config/OkHttpConfiguration.java | 73 +++++++++ .../com/sdm/submit/config/RedisConfig.java | 45 ++++++ .../submit/config/ScheduledTaskConfig.java | 21 +++ .../com/sdm/submit/config/SwaggerConfig.java | 22 +++ .../config/mybatis/DBContextHolder.java | 48 ++++++ .../sdm/submit/config/mybatis/DBTypeEnum.java | 10 ++ .../submit/config/mybatis/DatabasePlugin.java | 88 +++++++++++ .../config/mybatis/DynamicDataSource.java | 17 +++ .../config/mybatis/MybatisPlusConfig.java | 97 ++++++++++++ .../thread/SubmitCommonThreadPoolConfig.java | 74 +++++++++ .../sdm/submit/controller/TestController.java | 66 ++++++++ .../main/resources/META-INF/spring.factories | 1 + submit/src/main/resources/application-dev.yml | 127 ++++++++++++++++ .../src/main/resources/application-local.yml | 117 +++++++++++++++ .../src/main/resources/application-prod.yml | 109 ++++++++++++++ .../src/main/resources/application-test.yml | 101 +++++++++++++ submit/src/main/resources/application.yml | 3 + submit/src/main/resources/bin/log.sh | 13 ++ submit/src/main/resources/bin/restart.sh | 25 +++ submit/src/main/resources/bin/start.sh | 74 +++++++++ submit/src/main/resources/bin/status.sh | 20 +++ submit/src/main/resources/bin/stop.sh | 40 +++++ submit/src/main/resources/logback.xml | 89 +++++++++++ system/src/main/resources/logback.xml | 30 +++- task/src/main/resources/logback.xml | 30 +++- 39 files changed, 1939 insertions(+), 9 deletions(-) create mode 100644 common/src/main/java/com/sdm/common/common/mdc/FeignMdcRequestInterceptor.java create mode 100644 common/src/main/java/com/sdm/common/common/mdc/HttpFilterConfig.java create mode 100644 common/src/main/java/com/sdm/common/common/mdc/MdcTaskDecorator.java create mode 100644 common/src/main/java/com/sdm/common/common/mdc/TraceIdFilter.java create mode 100644 common/src/main/java/com/sdm/common/utils/log/CoreLogger.java create mode 100644 submit/pom.xml create mode 100644 submit/src/main/java/com/sdm/submit/SubmitApplication.java create mode 100644 submit/src/main/java/com/sdm/submit/config/DecryptEnvironmentPostProcessor.java create mode 100644 submit/src/main/java/com/sdm/submit/config/MinioConfig.java create mode 100644 submit/src/main/java/com/sdm/submit/config/OkHttpConfiguration.java create mode 100644 submit/src/main/java/com/sdm/submit/config/RedisConfig.java create mode 100644 submit/src/main/java/com/sdm/submit/config/ScheduledTaskConfig.java create mode 100644 submit/src/main/java/com/sdm/submit/config/SwaggerConfig.java create mode 100644 submit/src/main/java/com/sdm/submit/config/mybatis/DBContextHolder.java create mode 100644 submit/src/main/java/com/sdm/submit/config/mybatis/DBTypeEnum.java create mode 100644 submit/src/main/java/com/sdm/submit/config/mybatis/DatabasePlugin.java create mode 100644 submit/src/main/java/com/sdm/submit/config/mybatis/DynamicDataSource.java create mode 100644 submit/src/main/java/com/sdm/submit/config/mybatis/MybatisPlusConfig.java create mode 100644 submit/src/main/java/com/sdm/submit/config/thread/SubmitCommonThreadPoolConfig.java create mode 100644 submit/src/main/java/com/sdm/submit/controller/TestController.java create mode 100644 submit/src/main/resources/META-INF/spring.factories create mode 100644 submit/src/main/resources/application-dev.yml create mode 100644 submit/src/main/resources/application-local.yml create mode 100644 submit/src/main/resources/application-prod.yml create mode 100644 submit/src/main/resources/application-test.yml create mode 100644 submit/src/main/resources/application.yml create mode 100644 submit/src/main/resources/bin/log.sh create mode 100644 submit/src/main/resources/bin/restart.sh create mode 100644 submit/src/main/resources/bin/start.sh create mode 100644 submit/src/main/resources/bin/status.sh create mode 100644 submit/src/main/resources/bin/stop.sh create mode 100644 submit/src/main/resources/logback.xml diff --git a/capability/src/main/resources/logback.xml b/capability/src/main/resources/logback.xml index 6a733e3b..3571bfbb 100644 --- a/capability/src/main/resources/logback.xml +++ b/capability/src/main/resources/logback.xml @@ -6,7 +6,10 @@ - + + + + @@ -36,6 +39,30 @@ + + + ${LOG_HOME}/core.log + + ${LOG_HOME}/core.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + + [%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%15.15t] %X{callerInfo} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + + + INFO + + + + + + + + + diff --git a/common/pom.xml b/common/pom.xml index 830bdb73..5243b9f3 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -45,6 +45,15 @@ org.springdoc springdoc-openapi-starter-webmvc-ui + + + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + provided + + diff --git a/common/src/main/java/com/sdm/common/common/mdc/FeignMdcRequestInterceptor.java b/common/src/main/java/com/sdm/common/common/mdc/FeignMdcRequestInterceptor.java new file mode 100644 index 00000000..098f6922 --- /dev/null +++ b/common/src/main/java/com/sdm/common/common/mdc/FeignMdcRequestInterceptor.java @@ -0,0 +1,19 @@ +package com.sdm.common.common.mdc; + +import feign.RequestInterceptor; +import feign.RequestTemplate; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.MDC; +import org.springframework.stereotype.Component; + +@Component +public class FeignMdcRequestInterceptor implements RequestInterceptor { + @Override + public void apply(RequestTemplate template) { + // 这个apply方法会在每次Feign客户端方法调用前执行 + String traceId = MDC.get("traceId"); + if (StringUtils.isNotBlank(traceId)) { + template.header("X-Trace-Id", traceId); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/sdm/common/common/mdc/HttpFilterConfig.java b/common/src/main/java/com/sdm/common/common/mdc/HttpFilterConfig.java new file mode 100644 index 00000000..eff1d851 --- /dev/null +++ b/common/src/main/java/com/sdm/common/common/mdc/HttpFilterConfig.java @@ -0,0 +1,15 @@ +package com.sdm.common.common.mdc; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class HttpFilterConfig { + @Bean + public FilterRegistrationBean traceIdFilter() { + FilterRegistrationBean bean = new FilterRegistrationBean<>(new TraceIdFilter()); + bean.setOrder(1); + return bean; + } +} diff --git a/common/src/main/java/com/sdm/common/common/mdc/MdcTaskDecorator.java b/common/src/main/java/com/sdm/common/common/mdc/MdcTaskDecorator.java new file mode 100644 index 00000000..c4c097f6 --- /dev/null +++ b/common/src/main/java/com/sdm/common/common/mdc/MdcTaskDecorator.java @@ -0,0 +1,23 @@ +package com.sdm.common.common.mdc; + +import org.slf4j.MDC; +import org.springframework.core.task.TaskDecorator; + +import java.util.Map; + +public class MdcTaskDecorator implements TaskDecorator { + @Override + public Runnable decorate(Runnable runnable) { + Map contextMap = MDC.getCopyOfContextMap(); + return () -> { + try { + if (contextMap != null) { + MDC.setContextMap(contextMap); + } + runnable.run(); + } finally { + MDC.clear(); + } + }; + } +} diff --git a/common/src/main/java/com/sdm/common/common/mdc/TraceIdFilter.java b/common/src/main/java/com/sdm/common/common/mdc/TraceIdFilter.java new file mode 100644 index 00000000..87be0ffe --- /dev/null +++ b/common/src/main/java/com/sdm/common/common/mdc/TraceIdFilter.java @@ -0,0 +1,62 @@ +package com.sdm.common.common.mdc; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.MDC; + +import java.io.IOException; +import java.util.UUID; + + + +// 拦截所有 HTTP 请求 +public class TraceIdFilter implements Filter { + + /** + * MDC 中存储 traceId 的 key(需与日志格式中的 %X{traceId} 对应) + */ + public static final String TRACE_ID_KEY = "traceId"; + + /** + * 响应头中返回 traceId 的 key(前端可通过此 key 获取) + */ + public static final String TRACE_ID_HEADER = "X-Trace-Id"; + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + try { + // 1. 生成或获取 traceId(优先从请求头获取,支持前端传递,便于联调) + String traceId = request.getHeader(TRACE_ID_HEADER); + if (traceId == null || traceId.trim().isEmpty()) { + // 生成 UUID 并去除横杠(32位,简洁易读) + traceId = UUID.randomUUID().toString().replace("-", ""); + } + + // 2. 存入 MDC(供日志打印使用,所有日志框架可通过 %X{traceId} 获取) + MDC.put(TRACE_ID_KEY, traceId); + + // 3. 写入响应头(返回给前端,便于前端排查问题时匹配日志) + response.setHeader(TRACE_ID_HEADER, traceId); + + // 4. 放行请求,继续执行后续过滤器/控制器 + filterChain.doFilter(request, response); + + } finally { + // 5. 清除 MDC 中的 traceId(关键!避免线程池复用导致的 traceId 污染) + MDC.remove(TRACE_ID_KEY); + } + } + + // 初始化和销毁方法可空实现(无需额外操作) + @Override + public void init(FilterConfig filterConfig) throws ServletException {} + + @Override + public void destroy() {} +} \ No newline at end of file diff --git a/common/src/main/java/com/sdm/common/utils/log/CoreLogger.java b/common/src/main/java/com/sdm/common/utils/log/CoreLogger.java new file mode 100644 index 00000000..08b734cd --- /dev/null +++ b/common/src/main/java/com/sdm/common/utils/log/CoreLogger.java @@ -0,0 +1,142 @@ +package com.sdm.common.utils.log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +/** + * 核心业务日志工具类 + * 特性: + * 1. 日志自动输出到 core.log + * 2. 打印原始调用类名、方法名和行号 + * 3. 支持 SLF4J 标准日志方法(info/error/debug 等) + */ +public class CoreLogger { + + private static final Logger coreLog = LoggerFactory.getLogger("coreLogger"); + + private static final String CALLER_INFO_KEY = "callerInfo"; + + // 私有构造器 + private CoreLogger() { + throw new AssertionError("工具类不允许实例化"); + } + + /** + * 获取原始调用位置信息(类名.方法名(行号)) + * 跳过工具类自身的调用栈,定位到真实业务代码 + */ + private static String getCallerInfo() { + // 获取当前线程调用栈 + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + + // 栈索引说明(根据实际调用链调整): + // 0: Thread.getStackTrace() + // 1: CoreLogger.getCallerInfo() + // 2: CoreLogger.xxx()(如 info/error 等工具方法) + // 3: 实际业务类的调用方法(目标位置) + if (stackTrace.length >= 4) { + StackTraceElement caller = stackTrace[3]; + return String.format( + "%s.%s(%d)", + caller.getClassName(), // 原始调用类名 + caller.getMethodName(), // 原始调用方法名 + caller.getLineNumber() // 原始调用行号 + ); + } + // 异常情况:无法获取调用栈时返回默认值 + return "UnknownCaller"; + } + + // -------------------- 以下为 SLF4J 标准日志方法封装 -------------------- + + public static void debug(String message) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.debug(message); + } finally { + MDC.remove(CALLER_INFO_KEY); // 清除 MDC,避免线程复用污染 + } + } + + public static void debug(String message, Object... args) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.debug(message, args); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void info(String message) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.info(message); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void info(String message, Object... args) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.info(message, args); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void warn(String message) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.warn(message); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void warn(String message, Object... args) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.warn(message, args); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void warn(String message, Throwable throwable) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.warn(message, throwable); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void error(String message) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.error(message); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void error(String message, Object... args) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.error(message, args); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } + + public static void error(String message, Throwable throwable) { + try { + MDC.put(CALLER_INFO_KEY, getCallerInfo()); + coreLog.error(message, throwable); + } finally { + MDC.remove(CALLER_INFO_KEY); + } + } +} \ No newline at end of file diff --git a/data/src/main/resources/logback.xml b/data/src/main/resources/logback.xml index 10e84a15..04d682e6 100644 --- a/data/src/main/resources/logback.xml +++ b/data/src/main/resources/logback.xml @@ -6,9 +6,9 @@ - + - + @@ -58,6 +58,30 @@ + + + ${LOG_HOME}/core.log + + ${LOG_HOME}/core.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + + [%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%15.15t] %X{callerInfo} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + + + INFO + + + + + + + + + diff --git a/pom.xml b/pom.xml index e69c406e..839b1fc9 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ data pbs system + submit common diff --git a/project/src/main/resources/logback.xml b/project/src/main/resources/logback.xml index 0e8a7747..279e8a09 100644 --- a/project/src/main/resources/logback.xml +++ b/project/src/main/resources/logback.xml @@ -6,7 +6,10 @@ - + + + + @@ -29,7 +32,7 @@ - ${CONSOLE_LOG_PATTERN} + ${FILE_LOG_PATTERN} UTF-8 @@ -38,6 +41,30 @@ + + + ${LOG_HOME}/core.log + + ${LOG_HOME}/core.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + + [%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%15.15t] %X{callerInfo} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + + + INFO + + + + + + + + + diff --git a/submit/pom.xml b/submit/pom.xml new file mode 100644 index 00000000..84be21a8 --- /dev/null +++ b/submit/pom.xml @@ -0,0 +1,141 @@ + + + 4.0.0 + + com.sdm + SDM + 1.0-SNAPSHOT + + submit + 0.0.1-SNAPSHOT + submit + submit + + 17 + UTF-8 + UTF-8 + 3.3.5 + + + + + com.sdm + common + 0.0.1-SNAPSHOT + + + * + * + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + + commons-net + commons-net + 3.11.1 + + + org.apache.commons + commons-lang3 + 3.14.0 + + + org.aspectj + aspectjweaver + + + javax.annotation + javax.annotation-api + 1.3.2 + + + com.squareup.okhttp3 + okhttp + 4.10.0 + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + + + + io.minio + minio + 8.5.7 + + + + + commons-io + commons-io + 2.11.0 + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/submit/src/main/java/com/sdm/submit/SubmitApplication.java b/submit/src/main/java/com/sdm/submit/SubmitApplication.java new file mode 100644 index 00000000..9c0d9cf8 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/SubmitApplication.java @@ -0,0 +1,19 @@ +package com.sdm.submit; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootApplication(scanBasePackages = {"com.sdm.submit","com.sdm.common"}) +@EnableDiscoveryClient +@EnableScheduling +@EnableFeignClients(basePackages = "com.sdm.common.feign") +public class SubmitApplication { + + public static void main(String[] args) { + SpringApplication.run(SubmitApplication.class, args); + } + +} diff --git a/submit/src/main/java/com/sdm/submit/config/DecryptEnvironmentPostProcessor.java b/submit/src/main/java/com/sdm/submit/config/DecryptEnvironmentPostProcessor.java new file mode 100644 index 00000000..a1b28215 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/DecryptEnvironmentPostProcessor.java @@ -0,0 +1,49 @@ +package com.sdm.submit.config; + +import com.sdm.common.utils.AESUtil; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.core.env.*; +import org.springframework.stereotype.Component; + +import java.util.Properties; + +@Component +public class DecryptEnvironmentPostProcessor implements EnvironmentPostProcessor { + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + Properties props = new Properties(); // 临时存储需要替换的配置 + // 假设加密密码前缀为 "ENC(",后缀为 ")" + MutablePropertySources propertySources = environment.getPropertySources(); + for (PropertySource propertySource : propertySources) { + if (propertySource instanceof EnumerablePropertySource) { + EnumerablePropertySource enumerablePropertySource = (EnumerablePropertySource) propertySource; + String[] propertyNames = enumerablePropertySource.getPropertyNames(); + // 遍历所有配置key:value + for (String propertyName : propertyNames) { + String propertyVal = environment.getProperty(propertyName); + // 根据自己写的规则来解析那些配置是需要解密的 + if (propertyVal != null && propertyVal.startsWith("ENC(") && propertyVal.endsWith(")")) { + // 解析得到加密的数据 + String encryptedValue = propertyVal.substring(4, propertyVal.length() - 1); + // 调用自定义工具类解密 + String decryptedValue = null; + try { + decryptedValue = AESUtil.decode(encryptedValue); + } catch (Exception e) { + throw new RuntimeException(e); + } + // 保存需要替换的配置 + props.put(propertyName, decryptedValue); + } + } + } + } + // 添加解密后的属性到环境中 + if (!props.isEmpty()) { + PropertiesPropertySource pps = new PropertiesPropertySource("decryptedProperties", props); + environment.getPropertySources().addFirst(pps); + } + } +} + diff --git a/submit/src/main/java/com/sdm/submit/config/MinioConfig.java b/submit/src/main/java/com/sdm/submit/config/MinioConfig.java new file mode 100644 index 00000000..0999feed --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/MinioConfig.java @@ -0,0 +1,40 @@ +package com.sdm.submit.config; + +import io.minio.MinioClient; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MinioConfig { + + @Value("${minio.endpoint}") + private String endpoint; + + @Value("${minio.port}") // API端口,默认9000 + private int port; + + @Value("${minio.access-key}") + private String accessKey; + + @Value("${minio.secret-key}") + private String secretKey; + + @Value("${minio.bucket-name}") + private String bucketName; + + @Value("${minio.secure}") + private boolean secure; + + @Bean + public MinioClient minioClient() { + return MinioClient.builder() + .endpoint(endpoint, port, secure) + .credentials(accessKey, secretKey) + .build(); + } + + public String getBucketName() { + return bucketName; + } +} diff --git a/submit/src/main/java/com/sdm/submit/config/OkHttpConfiguration.java b/submit/src/main/java/com/sdm/submit/config/OkHttpConfiguration.java new file mode 100644 index 00000000..c69e42fc --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/OkHttpConfiguration.java @@ -0,0 +1,73 @@ +package com.sdm.submit.config; + +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.concurrent.TimeUnit; + +@Configuration +public class OkHttpConfiguration { + + @Bean + public OkHttpClient okHttpClient() { + return new OkHttpClient.Builder() + .sslSocketFactory(sslSocketFactory(), x509TrustManager()) + //是否开启缓存 + .retryOnConnectionFailure(true) + .connectionPool(pool()) + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(60, TimeUnit.SECONDS) + .hostnameVerifier((hostname, session) -> true) + .protocols(Collections.singletonList(Protocol.HTTP_1_1)) + .build(); + } + + @Bean + public X509TrustManager x509TrustManager() { + return new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + + } + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { + + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + } + + @Bean + public SSLSocketFactory sslSocketFactory() { + try { + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Bean + public ConnectionPool pool() { + return new ConnectionPool(5000, 300, TimeUnit.SECONDS); + } +} diff --git a/submit/src/main/java/com/sdm/submit/config/RedisConfig.java b/submit/src/main/java/com/sdm/submit/config/RedisConfig.java new file mode 100644 index 00000000..e30fa1c5 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/RedisConfig.java @@ -0,0 +1,45 @@ +package com.sdm.submit.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + @Bean(name = "redisTemplate") + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); + RedisSerializer redisSerializer = new StringRedisSerializer(); + + template.setConnectionFactory(factory); + // key序列化方式 + template.setKeySerializer(redisSerializer); + // value序列化 + template.setValueSerializer(redisSerializer); + // value hashmap序列化 + template.setHashValueSerializer(redisSerializer); + // key haspmap序列化 + template.setHashKeySerializer(redisSerializer); + + return template; + } + + @Bean(name = "bytesRedisTemplate") + public RedisTemplate bytesRedisTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(connectionFactory); + // 设置key和value的序列化规则 + redisTemplate.setValueSerializer(RedisSerializer.byteArray()); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.afterPropertiesSet(); + + return redisTemplate; + } +} + + + diff --git a/submit/src/main/java/com/sdm/submit/config/ScheduledTaskConfig.java b/submit/src/main/java/com/sdm/submit/config/ScheduledTaskConfig.java new file mode 100644 index 00000000..8e2e6a98 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/ScheduledTaskConfig.java @@ -0,0 +1,21 @@ +package com.sdm.submit.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.SchedulingConfigurer; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.config.ScheduledTaskRegistrar; + +/** + * 解决多个定时任务单线程有任务不能执行的问题 + * + */ +@Configuration +public class ScheduledTaskConfig implements SchedulingConfigurer { + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); + taskScheduler.setPoolSize(5); + taskScheduler.initialize(); + taskRegistrar.setTaskScheduler(taskScheduler); + } +} diff --git a/submit/src/main/java/com/sdm/submit/config/SwaggerConfig.java b/submit/src/main/java/com/sdm/submit/config/SwaggerConfig.java new file mode 100644 index 00000000..b2e2a070 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/SwaggerConfig.java @@ -0,0 +1,22 @@ +package com.sdm.submit.config; + +import io.swagger.v3.oas.models.ExternalDocumentation; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SwaggerConfig { + @Bean + public OpenAPI openAPI() { + return new OpenAPI() + .info(new Info() + .title("SPDM系统-作业提交模块") + .description("SPDM系统-作业提交模块接口文档") + .version("V1")) + .externalDocs(new ExternalDocumentation() + .description("作业提交模块") + .url("/")); + } +} diff --git a/submit/src/main/java/com/sdm/submit/config/mybatis/DBContextHolder.java b/submit/src/main/java/com/sdm/submit/config/mybatis/DBContextHolder.java new file mode 100644 index 00000000..97aca627 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/mybatis/DBContextHolder.java @@ -0,0 +1,48 @@ +package com.sdm.submit.config.mybatis; + +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @Author xuyundi + * @Date 2023/7/21 + * @Note + */ +@Slf4j +public class DBContextHolder { + private static final ThreadLocal contextHolder = new ThreadLocal<>(); + + private static final AtomicInteger counter = new AtomicInteger(-1); + + public static void set(DBTypeEnum dbType) { + contextHolder.set(dbType); + } + + public static DBTypeEnum get() { + return contextHolder.get(); + } + + public static void master() { + set(DBTypeEnum.MASTER); + log.info("切换到master"); + } + + public static void slave() { + set(DBTypeEnum.SLAVE); + log.info("切换到slave"); + + // 如果有多个从库,可通过轮询进行切换 +// int index = counter.getAndIncrement() % 2; +// if (counter.get() > 9999) { +// counter.set(-1); +// } +// if (index == 0) { +// set(DBTypeEnum.SLAVE1); +// log.info("切换到slave1"); +// }else { +// set(DBTypeEnum.SLAVE2); +// log.info("切换到slave2"); +// } + } +} diff --git a/submit/src/main/java/com/sdm/submit/config/mybatis/DBTypeEnum.java b/submit/src/main/java/com/sdm/submit/config/mybatis/DBTypeEnum.java new file mode 100644 index 00000000..45b9e97f --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/mybatis/DBTypeEnum.java @@ -0,0 +1,10 @@ +package com.sdm.submit.config.mybatis; + +/** + * @Author xuyundi + * @Date 2023/7/21 + * @Note + */ +public enum DBTypeEnum { + MASTER, SLAVE +} diff --git a/submit/src/main/java/com/sdm/submit/config/mybatis/DatabasePlugin.java b/submit/src/main/java/com/sdm/submit/config/mybatis/DatabasePlugin.java new file mode 100644 index 00000000..fb7eb5e7 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/mybatis/DatabasePlugin.java @@ -0,0 +1,88 @@ +package com.sdm.submit.config.mybatis; + +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.executor.keygen.SelectKeyGenerator; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @Author xuyundi + * @Date 2023/7/21 + * @Note + */ +@Slf4j +@Intercepts({ + @Signature(type = Executor.class, method = "update", args = { + MappedStatement.class, Object.class}), + @Signature(type = Executor.class, method = "query", args = { + MappedStatement.class, Object.class, RowBounds.class, + ResultHandler.class})}) +public class DatabasePlugin implements Interceptor { + + private static final String REGEX = ".*insert\\u0020.*|.*delete\\u0020.*|.*update\\u0020.*"; + + private static final Map cacheMap = new ConcurrentHashMap<>(); + + @Override + public Object intercept(Invocation invocation) throws Throwable { + + boolean synchronizationActive = TransactionSynchronizationManager.isSynchronizationActive(); + if (!synchronizationActive) { + Object[] objects = invocation.getArgs(); + MappedStatement ms = (MappedStatement) objects[0]; + + DBTypeEnum databaseType = null; + + if ((databaseType = cacheMap.get(ms.getId())) == null) { + //读方法 + if (ms.getSqlCommandType().equals(SqlCommandType.SELECT)) { + //!selectKey 为自增id查询主键(SELECT LAST_INSERT_ID() )方法,使用主库 + if (ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) { + databaseType = DBTypeEnum.MASTER; + } else { + BoundSql boundSql = ms.getSqlSource().getBoundSql(objects[1]); + String sql = boundSql.getSql().toLowerCase(Locale.CHINA).replaceAll("[\\t\\n\\r]", " "); + if (sql.matches(REGEX)) { + databaseType = DBTypeEnum.MASTER; + } else { + databaseType = DBTypeEnum.SLAVE; + } + } + } else { + databaseType = DBTypeEnum.MASTER; + } +// log.warn("设置方法[{}] use [{}] Strategy, SqlCommandType [{}]..", ms.getId(), databaseType.name(), ms.getSqlCommandType().name()); + cacheMap.put(ms.getId(), databaseType); + } + DBContextHolder.set(databaseType); + } + + return invocation.proceed(); + } + + @Override + public Object plugin(Object target) { + if (target instanceof Executor) { + return Plugin.wrap(target, this); + } else { + return target; + } + } + + @Override + public void setProperties(Properties properties) { + + } + +} \ No newline at end of file diff --git a/submit/src/main/java/com/sdm/submit/config/mybatis/DynamicDataSource.java b/submit/src/main/java/com/sdm/submit/config/mybatis/DynamicDataSource.java new file mode 100644 index 00000000..10fe9d36 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/mybatis/DynamicDataSource.java @@ -0,0 +1,17 @@ +package com.sdm.submit.config.mybatis; + +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; +import org.springframework.lang.Nullable; + +/** + * @Author xuyundi + * @Date 2023/7/21 + * @Note + */ +public class DynamicDataSource extends AbstractRoutingDataSource { + @Nullable + @Override + protected Object determineCurrentLookupKey() { + return DBContextHolder.get(); + } +} diff --git a/submit/src/main/java/com/sdm/submit/config/mybatis/MybatisPlusConfig.java b/submit/src/main/java/com/sdm/submit/config/mybatis/MybatisPlusConfig.java new file mode 100644 index 00000000..29dd4d29 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/mybatis/MybatisPlusConfig.java @@ -0,0 +1,97 @@ +package com.sdm.submit.config.mybatis; + +import com.baomidou.mybatisplus.core.MybatisConfiguration; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import javax.sql.DataSource; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author xuyundi + * @Date 2023/7/21 + * @Note + */ +@Configuration +@MapperScan(basePackages = "com.sdm.submit.dao", sqlSessionFactoryRef = "mybatisSqlSessionFactoryAdaptor") +public class MybatisPlusConfig { + + + @Value("${spring.datasource.slave.enable}") + private boolean slaveEnable; + +// /** +// * mybatis-plus分页插件 +// */ +// @Bean +// public PaginationInterceptor paginationInterceptor() { +// PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); +// paginationInterceptor.setDialectType(DBType.MYSQL.getDb()); +// return paginationInterceptor; +// } + + @Bean(name = "masterDataSource") + @Qualifier("masterDataSource") + @ConfigurationProperties(prefix = "spring.datasource.master") + public DataSource masterDataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "slaveDataSource") + @Qualifier("slaveDataSource") + @ConfigurationProperties(prefix = "spring.datasource.slave") + public DataSource slaveDataSource() { + return DataSourceBuilder.create().build(); + } + + /** + * 构造多数据源连接池 + * Master 数据源连接池采用 HikariDataSource + * Slave 数据源连接池采用 DruidDataSource + * + * @param master + * @param slave + * @return + */ + @Bean + @Primary + public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource master, + @Qualifier("slaveDataSource") DataSource slave) { + Map targetDataSources = new HashMap<>(); + targetDataSources.put(DBTypeEnum.MASTER, master); + targetDataSources.put(DBTypeEnum.SLAVE, slave); + + DynamicDataSource dataSource = new DynamicDataSource(); + dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法 + dataSource.setDefaultTargetDataSource(slave);// 默认的datasource设置为myTestDbDataSourcereturn dataSource; + return dataSource; + } + + @Bean(name = "mybatisSqlSessionFactoryAdaptor") + public MybatisSqlSessionFactoryBean sqlSessionFactory(@Qualifier("masterDataSource") DataSource master, + @Qualifier("slaveDataSource") DataSource slave) throws IOException { + MybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean(); + fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml")); + fb.setDataSource(this.dataSource(master, slave)); + // 设置开启下划线转驼峰 + MybatisConfiguration configuration = new MybatisConfiguration(); + configuration.setMapUnderscoreToCamelCase(true); + fb.setConfiguration(configuration); + // 是否启动多数据源配置,目的是方便多环境下在本地环境调试,不影响其他环境 + if (slaveEnable) { + fb.setPlugins(new DatabasePlugin()); + } + return fb; + } + +} \ No newline at end of file diff --git a/submit/src/main/java/com/sdm/submit/config/thread/SubmitCommonThreadPoolConfig.java b/submit/src/main/java/com/sdm/submit/config/thread/SubmitCommonThreadPoolConfig.java new file mode 100644 index 00000000..b84b1639 --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/config/thread/SubmitCommonThreadPoolConfig.java @@ -0,0 +1,74 @@ +package com.sdm.submit.config.thread; + +import com.sdm.common.common.mdc.MdcTaskDecorator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * 自定义线程池配置(JDK 17 + Spring Boot 兼容) + */ +@Configuration +public class SubmitCommonThreadPoolConfig { + + /** + * 核心线程数:线程池长期维持的最小线程数,即使空闲也不销毁(除非设置 allowCoreThreadTimeOut) + * 建议:CPU 密集型任务(如计算)= CPU 核心数 + 1;IO 密集型任务(如网络请求)= CPU 核心数 * 2 + */ + private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2; + + /** + * 最大线程数:线程池允许的最大线程数,当任务队列满时会创建新线程直到达到该值 + */ + private static final int MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 4; + + /** + * 队列容量:用于缓存任务的阻塞队列,当核心线程都在工作时,新任务会进入该队列等待 + */ + private static final int QUEUE_CAPACITY = 100; + + /** + * 空闲线程存活时间:当线程数超过核心线程数时,多余的空闲线程的存活时间(单位:秒) + */ + private static final int KEEP_ALIVE_SECONDS = 60; + + /** + * 线程名称前缀:用于区分不同线程池的线程,便于日志追踪 + */ + private static final String THREAD_NAME_PREFIX = "custom-thread-"; + + /** + * 自定义线程池(默认名称:customExecutor) + * 可通过 @Async("customExecutor") 指定使用该线程池 + */ + @Bean(name = "submitCommonExecutor") + public Executor customThreadPool() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + + // 核心线程数 + executor.setCorePoolSize(CORE_POOL_SIZE); + // 最大线程数 + executor.setMaxPoolSize(MAX_POOL_SIZE); + // 队列容量 + executor.setQueueCapacity(QUEUE_CAPACITY); + // 空闲线程存活时间 + executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS); + // 线程名称前缀 + executor.setThreadNamePrefix(THREAD_NAME_PREFIX); + executor.setTaskDecorator(new MdcTaskDecorator()); + // 线程池拒绝策略:当任务数超过最大线程数+队列容量时的处理方式 + // JDK 17 支持的策略: + // - ThreadPoolExecutor.AbortPolicy(默认):直接抛出 RejectedExecutionException + // - ThreadPoolExecutor.CallerRunsPolicy:由提交任务的线程执行(减缓提交速度,适用于并发不高的场景) + // - ThreadPoolExecutor.DiscardPolicy:直接丢弃新任务,不抛出异常 + // - ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列中最旧的任务,再尝试提交新任务 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + + // 初始化线程池(必须调用,否则线程池不生效) + executor.initialize(); + return executor; + } +} \ No newline at end of file diff --git a/submit/src/main/java/com/sdm/submit/controller/TestController.java b/submit/src/main/java/com/sdm/submit/controller/TestController.java new file mode 100644 index 00000000..3b78fa2b --- /dev/null +++ b/submit/src/main/java/com/sdm/submit/controller/TestController.java @@ -0,0 +1,66 @@ +package com.sdm.submit.controller; + +import com.alibaba.fastjson2.JSONObject; +import com.sdm.common.common.SdmResponse; +import com.sdm.common.entity.req.system.LaunchApproveReq; +import com.sdm.common.feign.inter.data.IDataFeignClient; +import com.sdm.common.utils.log.CoreLogger; +import io.swagger.v3.oas.annotations.Operation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +@Slf4j +@RestController +public class TestController { + + @Autowired + @Qualifier(value = "submitCommonExecutor") + private Executor submitCommonExecutor; + + @Autowired + private IDataFeignClient dataFeignClient; + + // SdmResponse + @GetMapping("/testLog") + @Operation(summary = "测试日志打印", description = "测试日志打印") + public String testLog() { + log.debug("testLog start:这是一个普通debug日志"); + log.warn("testLog start:这是一个普通warn日志"); + log.info("testLog start:这是一个普通info日志"); + log.error("testLog start:这是一个普通日志"); + CoreLogger.debug("testLog start:{}", LocalDateTime.now()); + CoreLogger.info("testLog start:{}", LocalDateTime.now()); + String str1="aaaaa-str"; + String str2="bbbbb-str"; + CoreLogger.warn("testLog param1:{}, param2{}", str1,str2); + try { + int m = 1/0; + } catch (Exception e) { + CoreLogger.error("testLog end error:{}", e.getMessage()); + CoreLogger.error("testLog end error Stack",e); + } + + for (int i = 0; i <2 ; i++) { + CompletableFuture.runAsync(()->printLogs("测试自定义异步线程池日志打印"),submitCommonExecutor); + } + CoreLogger.info("开始测试feign远程调用"); + SdmResponse sdmResponse = dataFeignClient.approveDataFile(new LaunchApproveReq()); + CoreLogger.info("测试feign远程调用结果:{}", JSONObject.toJSONString(sdmResponse)); + return "submit ok"; + } + + private void printLogs(String str) { + CoreLogger.debug("testLog start:这是一个异步debug日志:{}",str); + CoreLogger.warn("testLog start:这是一个异步warn日志:{}",str); + CoreLogger.info("testLog start:这是一个异步info日志:{}",str); + CoreLogger.error("testLog start:这是一个异步日志:{}",str); + } + +} diff --git a/submit/src/main/resources/META-INF/spring.factories b/submit/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..06635601 --- /dev/null +++ b/submit/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.env.EnvironmentPostProcessor=com.sdm.submit.config.DecryptEnvironmentPostProcessor \ No newline at end of file diff --git a/submit/src/main/resources/application-dev.yml b/submit/src/main/resources/application-dev.yml new file mode 100644 index 00000000..b42e344e --- /dev/null +++ b/submit/src/main/resources/application-dev.yml @@ -0,0 +1,127 @@ +server: + port: 7108 + +spring: + application: + name: submit + datasource: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + hikari: + maximum-pool-size: 450 # 连接池最大连接数(关键!) + minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁) + idle-timeout: 300000 # 空闲连接超时时间(5分钟) + max-lifetime: 600000 # 连接最大存活时间(10分钟) + connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞) + master: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + slave: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + enable: true + cloud: + nacos: + discovery: + server-addr: 192.168.65.161:8848 + group: DEV_GROUP + enabled: true + # username: nacos + # password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + data: + redis: + # Redis默认情况下有16个分片(库),这里配置具体使用的分片,默认是0 + database: 0 + # redis服务器地址(填写自己的服务器地址) + host: 192.168.2.166 + # redis端口(默认6379) + port: 6379 + #redis连接超时等待,10秒 + timeout: PT10S + # redis访问密码(默认为空) + password: + lettuce: + pool: + # 连接池最大连接数(使用负值表示没有限制) 默认 8 + max-active: 50 + # 连接池中的最大空闲连接 默认 8 + max-idle: 20 + # 连接池中的最小空闲连接 默认 0 + min-idle: 1 + # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1,这里配置10s + max-wait: PT10S + # password: + # sentinel: + # master: mymaster + # nodes: 10.18.109.50:26379,10.18.109.51:26379,10.18.109.52:26379 + servlet: + multipart: + # 单个文件的最大值 + max-file-size: 500MB + # 上传文件总的最大值 + max-request-size: 10240MB + +management: + endpoints: + web: + exposure: + include: health,info + endpoint: + health: + show-details: always + +mybatis-plus: + configuration: + map-underscore-to-camel-case: true + auto-mapping-behavior: full + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + # cache-enabled: true + mapper-locations: classpath*:mapper/**/*.xml + global-config: + # 逻辑删除配置 + db-config: + # 删除前 + logic-not-delete-value: 1 + # 删除后 + logic-delete-value: 0 + +# MyBatis SQL日志配置 +logging: + level: + com.baomidou.mybatisplus.core.MybatisConfiguration: debug + com.baomidou.mybatisplus.core.override.MybatisMapperRegistry: trace + com.sdm.data.mapper: debug + java.sql: debug + java.sql.Connection: debug + java.sql.Statement: debug + java.sql.PreparedStatement: debug + +lombok: + anyConstructor: + addConstructorProperties: true + + +#logging: +# config: ./config/logback.xml + + +#地址: https://play.min.io +#凭据: +#账号: minioadmin / 密码: minioadmin +#特点: +#由 MinIO 官方提供,用于演示和测试。 +#公开可访问,但数据可能定期清理。 +#支持 S3 API,适合快速验证代码 +minio: + endpoint: 192.168.65.161 + port: 9000 + access-key: minioadmin + secret-key: minioadmin + secure: false + bucket-name: spdm \ No newline at end of file diff --git a/submit/src/main/resources/application-local.yml b/submit/src/main/resources/application-local.yml new file mode 100644 index 00000000..c7416a93 --- /dev/null +++ b/submit/src/main/resources/application-local.yml @@ -0,0 +1,117 @@ +server: + port: 7108 + +spring: + application: + name: submit + datasource: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + hikari: + maximum-pool-size: 450 # 连接池最大连接数(关键!) + minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁) + idle-timeout: 300000 # 空闲连接超时时间(5分钟) + max-lifetime: 600000 # 连接最大存活时间(10分钟) + connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞) + master: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + slave: + username: root + password: mysql + jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + enable: true + cloud: + nacos: + discovery: + server-addr: 192.168.65.161:8848/nacos + group: LOCAL_GROUP + enabled: true +# username: nacos +# password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + data: + redis: + # Redis默认情况下有16个分片(库),这里配置具体使用的分片,默认是0 + database: 0 + # redis服务器地址(填写自己的服务器地址) + host: 192.168.2.166 + # redis端口(默认6379) + port: 6379 + #redis连接超时等待,10秒 + timeout: PT10S + # redis访问密码(默认为空) + password: + lettuce: + pool: + # 连接池最大连接数(使用负值表示没有限制) 默认 8 + max-active: 50 + # 连接池中的最大空闲连接 默认 8 + max-idle: 20 + # 连接池中的最小空闲连接 默认 0 + min-idle: 1 + # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1,这里配置10s + max-wait: PT10S +# password: +# sentinel: +# master: mymaster +# nodes: 10.18.109.50:26379,10.18.109.51:26379,10.18.109.52:26379 + servlet: + multipart: + # 单个文件的最大值 + max-file-size: 500MB + # 上传文件总的最大值 + max-request-size: 10240MB + +mybatis-plus: + configuration: + map-underscore-to-camel-case: true + auto-mapping-behavior: full + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + # cache-enabled: true + mapper-locations: classpath*:mapper/**/*.xml + global-config: + # 逻辑删除配置 + db-config: + # 删除前 + logic-not-delete-value: 1 + # 删除后 + logic-delete-value: 0 + +# MyBatis SQL日志配置 +logging: + level: + com.baomidou.mybatisplus.core.MybatisConfiguration: debug + com.baomidou.mybatisplus.core.override.MybatisMapperRegistry: trace + com.sdm.data.mapper: debug + java.sql: debug + java.sql.Connection: debug + java.sql.Statement: debug + java.sql.PreparedStatement: debug + +lombok: + anyConstructor: + addConstructorProperties: true + +#logging: +# config: ./config/logback.xml + + +#地址: https://play.min.io +#凭据: +#账号: minioadmin / 密码: minioadmin +#特点: +#由 MinIO 官方提供,用于演示和测试。 +#公开可访问,但数据可能定期清理。 +#支持 S3 API,适合快速验证代码 +minio: + endpoint: 192.168.65.161 + port: 9000 + access-key: minioadmin + secret-key: minioadmin + secure: false + bucket-name: spdm \ No newline at end of file diff --git a/submit/src/main/resources/application-prod.yml b/submit/src/main/resources/application-prod.yml new file mode 100644 index 00000000..0fd7c765 --- /dev/null +++ b/submit/src/main/resources/application-prod.yml @@ -0,0 +1,109 @@ +server: + port: 7108 + +spring: + application: + name: submit + datasource: + hikari: + maximum-pool-size: 450 # 连接池最大连接数(关键!) + minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁) + idle-timeout: 300000 # 空闲连接超时时间(5分钟) + max-lifetime: 600000 # 连接最大存活时间(10分钟) + connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞) + master: + username: root + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + jdbc-url: jdbc:mysql://172.27.2.238:3306/spdm_prod?useUnicode=true&characterEncoding=utf-8&useSSL=true&clientCertificateKeyStoreUrl=file:/opt/spdm/mysql_ssl/keystoremysql&clientCertificateKeyStorePassword=guangqi&trustCertificateKeyStoreUrl=file:/opt/spdm/mysql_ssl/truststoremysql&trustCertificateKeyStorePassword=guangqi&serverTimezone=Asia/Shanghai +# jdbc-url: jdbc:mysql://10.30.10.210:3306/spdm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + slave: + username: root + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + jdbc-url: jdbc:mysql://172.27.2.238:3306/spdm_prod?useUnicode=true&characterEncoding=utf-8&useSSL=true&clientCertificateKeyStoreUrl=file:/opt/spdm/mysql_ssl/keystoremysql&clientCertificateKeyStorePassword=guangqi&trustCertificateKeyStoreUrl=file:/opt/spdm/mysql_ssl/truststoremysql&trustCertificateKeyStorePassword=guangqi&serverTimezone=Asia/Shanghai +# jdbc-url: jdbc:mysql://10.30.10.210:3306/spdm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + enable: true + cloud: + nacos: + discovery: + server-addr: 172.27.2.238:8848 + group: PROD_GROUP + enabled: true + username: nacos + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + namespace: 3 + data: + redis: + # Redis默认情况下有16个分片(库),这里配置具体使用的分片,默认是0 + database: 1 + # redis服务器地址(填写自己的服务器地址) + host: 172.27.2.238 + # redis端口(默认6379) + port: 6379 + #redis连接超时等待,10秒 + timeout: PT10S + # redis访问密码(默认为空) + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + lettuce: + pool: + # 连接池最大连接数(使用负值表示没有限制) 默认 8 + max-active: 50 + # 连接池中的最大空闲连接 默认 8 + max-idle: 20 + # 连接池中的最小空闲连接 默认 0 + min-idle: 1 + # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1,这里配置10s + max-wait: PT10S +# password: +# sentinel: +# master: mymaster +# nodes: 10.18.109.50:26379,10.18.109.51:26379,10.18.109.52:26379 + servlet: + multipart: + # 单个文件的最大值 + max-file-size: 500MB + # 上传文件总的最大值 + max-request-size: 10240MB + +mybatis-plus: + configuration: + map-underscore-to-camel-case: true + auto-mapping-behavior: full +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + mapper-locations: classpath*:mapper/**/*.xml + global-config: + # 逻辑删除配置 + db-config: + # 删除前 + logic-not-delete-value: 1 + # 删除后 + logic-delete-value: 0 + +#showSql +#logging: +# level: +# com.sdm.dao: debug + +lombok: + anyConstructor: + addConstructorProperties: true + +ftp: + host: 172.27.3.135 + port: 6318 + +#地址: https://play.min.io +#凭据: +#账号: minioadmin / 密码: minioadmin +#特点: +#由 MinIO 官方提供,用于演示和测试。 +#公开可访问,但数据可能定期清理。 +#支持 S3 API,适合快速验证代码 +minio: + endpoint: 192.168.65.161 + port: 9000 + access-key: minioadmin + secret-key: minioadmin + secure: false + bucket-name: spdm \ No newline at end of file diff --git a/submit/src/main/resources/application-test.yml b/submit/src/main/resources/application-test.yml new file mode 100644 index 00000000..6e4531e4 --- /dev/null +++ b/submit/src/main/resources/application-test.yml @@ -0,0 +1,101 @@ +server: + port: 7108 + +spring: + application: + name: submit + datasource: + hikari: + maximum-pool-size: 450 # 连接池最大连接数(关键!) + minimum-idle: 50 # 最小空闲连接数(与最大一致,避免频繁创建销毁) + idle-timeout: 300000 # 空闲连接超时时间(5分钟) + max-lifetime: 600000 # 连接最大存活时间(10分钟) + connection-timeout: 30000 # 获取连接超时时间(30秒,避免线程阻塞) + master: + username: root + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + jdbc-url: jdbc:mysql://172.27.2.235:3306/spdm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai +# jdbc-url: jdbc:mysql://10.30.10.210:3306/spdm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + slave: + username: root + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + jdbc-url: jdbc:mysql://172.27.2.235:3306/spdm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai +# jdbc-url: jdbc:mysql://10.30.10.210:3306/spdm?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + enable: true + cloud: + nacos: + discovery: + server-addr: 172.27.2.238:8848 + group: TEST_GROUP + enabled: true + username: nacos + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + data: + redis: + # Redis默认情况下有16个分片(库),这里配置具体使用的分片,默认是0 + database: 0 + # redis服务器地址(填写自己的服务器地址) + host: 172.27.2.238 + # redis端口(默认6379) + port: 6379 + #redis连接超时等待,10秒 + timeout: PT10S + # redis访问密码(默认为空) + password: ENC(+QKYnI6gAYu1SbLaZQTkZA==) + lettuce: + pool: + # 连接池最大连接数(使用负值表示没有限制) 默认 8 + max-active: 50 + # 连接池中的最大空闲连接 默认 8 + max-idle: 20 + # 连接池中的最小空闲连接 默认 0 + min-idle: 1 + # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1,这里配置10s + max-wait: PT10S + + servlet: + multipart: + # 单个文件的最大值 + max-file-size: 500MB + # 上传文件总的最大值 + max-request-size: 10240MB + +mybatis-plus: + configuration: + map-underscore-to-camel-case: true + auto-mapping-behavior: full +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + mapper-locations: classpath*:mapper/**/*.xml + global-config: + # 逻辑删除配置 + db-config: + # 删除前 + logic-not-delete-value: 1 + # 删除后 + logic-delete-value: 0 + +#showSql +#logging: +# level: +# com.sdm.dao: debug + +lombok: + anyConstructor: + addConstructorProperties: true + +#地址: https://play.min.io +#凭据: +#账号: minioadmin / 密码: minioadmin +#特点: +#由 MinIO 官方提供,用于演示和测试。 +#公开可访问,但数据可能定期清理。 +#支持 S3 API,适合快速验证代码 +minio: + endpoint: 192.168.65.161 + port: 9000 + access-key: minioadmin + secret-key: minioadmin + secure: false + bucket-name: spdm diff --git a/submit/src/main/resources/application.yml b/submit/src/main/resources/application.yml new file mode 100644 index 00000000..caf4dfcd --- /dev/null +++ b/submit/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: dev \ No newline at end of file diff --git a/submit/src/main/resources/bin/log.sh b/submit/src/main/resources/bin/log.sh new file mode 100644 index 00000000..2dc63d51 --- /dev/null +++ b/submit/src/main/resources/bin/log.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Spring Boot 项目日志查看脚本 +LOG_HOME="/home/app/data/logs" +LOG_FILE="${LOG_HOME}/running.log" + + +# 查看实时日志 +if [ ! -f "${LOG_FILE}" ]; then + echo "日志文件不存在:${LOG_FILE}(可能项目未启动)" + exit 1 +fi +echo "正在查看实时运行日志(按 Ctrl+C 退出)... 日志路径:${LOG_FILE}" +tail -f "${LOG_FILE}" diff --git a/submit/src/main/resources/bin/restart.sh b/submit/src/main/resources/bin/restart.sh new file mode 100644 index 00000000..daed40e3 --- /dev/null +++ b/submit/src/main/resources/bin/restart.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Spring Boot 项目重启脚本 + +# 定义基础路径(公共参数) +BASE_DIR="/home/app/data" + +echo "=== 开始重启项目 ===" + +# 先停止服务 +if [ -f "${BASE_DIR}/stop.sh" ]; then + "${BASE_DIR}/stop.sh" +else + echo "错误:未找到停止脚本 ${BASE_DIR}/stop.sh" + exit 1 +fi + +# 再启动服务 +if [ -f "${BASE_DIR}/start.sh" ]; then + "${BASE_DIR}/start.sh" +else + echo "错误:未找到启动脚本 ${BASE_DIR}/start.sh" + exit 1 +fi + +echo "=== 重启操作完成 ===" \ No newline at end of file diff --git a/submit/src/main/resources/bin/start.sh b/submit/src/main/resources/bin/start.sh new file mode 100644 index 00000000..1c8e2df9 --- /dev/null +++ b/submit/src/main/resources/bin/start.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# Spring Boot 项目启动脚本(不修改logback配置,实时打印日志) +JAR_PATH="/home/app/data" +JAR_NAME="data-0.0.1-SNAPSHOT.jar" +FULL_JAR_PATH="${JAR_PATH}/${JAR_NAME}" + +# 与logback.xml保持一致的日志路径 +LOG_HOME="/home/app/data/logs" +LOG_FILE="${LOG_HOME}/running.log" + +# JVM参数 +JVM_OPTS="-Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOG_HOME}/heapdump.hprof" + +# 默认为交互模式(显示实时日志) +silent_mode=0 + +# 处理参数:如果传入 --silent 则启用静默模式 +if [ "$1" = "--silent" ]; then + silent_mode=1 +fi + +# 函数定义 +check_jar_exists() { + if [ ! -f "${FULL_JAR_PATH}" ]; then + echo "ERROR: Jar包不存在!路径:${FULL_JAR_PATH}" + exit 1 + fi +} + +get_running_pid() { + ps -ef | grep "${JAR_NAME}" | grep -v "grep" | awk '{print $2}' +} + +# 启动服务 +check_jar_exists + +PID=$(get_running_pid) +if [ -n "${PID}" ]; then + echo "项目已在运行中!PID: ${PID}" + exit 0 +fi + +# 确保日志目录存在 +if [ ! -d "${LOG_HOME}" ]; then + mkdir -p "${LOG_HOME}" + echo "日志目录不存在,已自动创建:${LOG_HOME}" +fi + +echo "正在启动项目... 实时日志如下(按 Ctrl+C 可退出查看,进程会继续运行)" +echo "======================================================================" + +# 启动项目并保留控制台输出 +nohup java ${JVM_OPTS} -jar "${FULL_JAR_PATH}" > "${LOG_FILE}" 2>&1 & + +# 获取刚启动的进程PID +NEW_PID=$(get_running_pid) + +# 实时显示日志 +if [ -n "${NEW_PID}" ]; then + # 根据模式决定是否显示实时日志 + if [ ${silent_mode} -eq 0 ]; then + echo "实时日志如下(按 Ctrl+C 可退出查看,进程会继续运行)" + tail -f "${LOG_FILE}" + fi + # 无论 tail 命令如何退出,都认为启动成功 + echo "======================================================================" + echo "项目启动成功!PID: ${NEW_PID}" + echo "日志文件路径:${LOG_FILE}" + exit 0 # 强制返回成功状态 +else + echo "======================================================================" + echo "项目启动失败!请查看日志:${LOG_FILE}" + exit 1 +fi diff --git a/submit/src/main/resources/bin/status.sh b/submit/src/main/resources/bin/status.sh new file mode 100644 index 00000000..52cc4ca5 --- /dev/null +++ b/submit/src/main/resources/bin/status.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Spring Boot 项目状态查询脚本 +JAR_NAME="data-0.0.1-SNAPSHOT.jar" +LOG_HOME="/home/app/data/logs" +LOG_FILE="${LOG_HOME}/running.log" + + +# 函数定义 +get_running_pid() { + ps -ef | grep "${JAR_NAME}" | grep -v "grep" | awk '{print $2}' +} + +# 查看服务状态 +PID=$(get_running_pid) +if [ -n "${PID}" ]; then + echo "项目运行中!PID: ${PID}" + echo "日志文件路径:${LOG_FILE}" +else + echo "项目未在运行中" +fi diff --git a/submit/src/main/resources/bin/stop.sh b/submit/src/main/resources/bin/stop.sh new file mode 100644 index 00000000..2b96b228 --- /dev/null +++ b/submit/src/main/resources/bin/stop.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Spring Boot 项目停止脚本 +JAR_NAME="data-0.0.1-SNAPSHOT.jar" + + +# 函数定义 +get_running_pid() { + ps -ef | grep "${JAR_NAME}" | grep -v "grep" | awk '{print $2}' +} + +# 停止服务 +PID=$(get_running_pid) +if [ -z "${PID}" ]; then + echo "项目未在运行中,无需停止" + exit 0 +fi + +echo "正在停止项目... PID: ${PID}" +kill -15 "${PID}" + +WAIT=0 +while [ ${WAIT} -lt 10 ]; do + if [ -z "$(get_running_pid)" ]; then + echo "项目已优雅停止" + exit 0 + fi + sleep 1 + WAIT=$((WAIT + 1)) +done + +echo "优雅停止超时,强制终止进程... PID: ${PID}" +kill -9 "${PID}" + +sleep 2 +if [ -z "$(get_running_pid)" ]; then + echo "项目已强制停止" +else + echo "ERROR: 进程终止失败!请手动检查:ps -ef | grep ${JAR_NAME}" + exit 1 +fi diff --git a/submit/src/main/resources/logback.xml b/submit/src/main/resources/logback.xml new file mode 100644 index 00000000..bdb1ed5b --- /dev/null +++ b/submit/src/main/resources/logback.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + ${LOG_HOME}/running.log + + ${LOG_HOME}/running.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + ${FILE_LOG_PATTERN} + + + INFO + + + + + + ${LOG_HOME}/running_debug.log + + ${LOG_HOME}/running_debug.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + ${FILE_LOG_PATTERN} + + + DEBUG + ACCEPT + DENY + + + + + + ${LOG_HOME}/core.log + + ${LOG_HOME}/core.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + + [%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%15.15t] %X{callerInfo} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + + + INFO + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/system/src/main/resources/logback.xml b/system/src/main/resources/logback.xml index e17db63c..886dffd0 100644 --- a/system/src/main/resources/logback.xml +++ b/system/src/main/resources/logback.xml @@ -6,7 +6,9 @@ - + + + @@ -39,10 +41,34 @@ - ${CONSOLE_LOG_PATTERN} + ${FILE_LOG_PATTERN} + + + ${LOG_HOME}/core.log + + ${LOG_HOME}/core.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + + [%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%15.15t] %X{callerInfo} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + + + INFO + + + + + + + + + diff --git a/task/src/main/resources/logback.xml b/task/src/main/resources/logback.xml index 3ba50778..637f91d1 100644 --- a/task/src/main/resources/logback.xml +++ b/task/src/main/resources/logback.xml @@ -6,7 +6,9 @@ - + + + @@ -39,10 +41,34 @@ - ${CONSOLE_LOG_PATTERN} + ${FILE_LOG_PATTERN} + + + ${LOG_HOME}/core.log + + ${LOG_HOME}/core.log.%d{yyyy-MM-dd}.%i.log + 30 + 500MB + 10MB + + + + [%X{traceId}] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%15.15t] %X{callerInfo} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} + + + INFO + + + + + + + + +