添加异步线程池配置.
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
package com.orion.ops.framework.common.config;
|
||||
|
||||
import com.orion.ops.framework.common.thread.ThreadPoolMdcTaskExecutor;
|
||||
import com.orion.spring.SpringHolder;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 应用配置类
|
||||
@@ -11,7 +18,9 @@ import org.springframework.context.annotation.Bean;
|
||||
* @version 1.0.0
|
||||
* @since 2023/6/20 10:34
|
||||
*/
|
||||
@EnableAsync
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(ThreadPoolConfig.class)
|
||||
public class OrionCommonAutoConfiguration {
|
||||
|
||||
/**
|
||||
@@ -22,4 +31,31 @@ public class OrionCommonAutoConfiguration {
|
||||
return new SpringHolder.ApplicationContextAwareStore();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持 MDC 的异步线程池
|
||||
* <p>
|
||||
* {@code @Async("asyncExecutor")}
|
||||
*
|
||||
* @return 异步线程池
|
||||
*/
|
||||
@Primary
|
||||
@Bean(name = "asyncExecutor")
|
||||
public TaskExecutor asyncExecutor(ThreadPoolConfig config) {
|
||||
ThreadPoolMdcTaskExecutor executor = new ThreadPoolMdcTaskExecutor();
|
||||
executor.setCorePoolSize(config.getCorePoolSize());
|
||||
executor.setMaxPoolSize(config.getMaxPoolSize());
|
||||
executor.setQueueCapacity(config.getQueueCapacity());
|
||||
executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
|
||||
executor.setAllowCoreThreadTimeOut(true);
|
||||
executor.setThreadNamePrefix("async-task-");
|
||||
// 设置等待所有任务执行结束再关闭线程池
|
||||
executor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
// 以确保应用最后能够被关闭
|
||||
executor.setAwaitTerminationSeconds(60);
|
||||
// 调用者调用拒绝策略
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.orion.ops.framework.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* 线程池配置类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/10 15:49
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "orion.thread.pool")
|
||||
public class ThreadPoolConfig {
|
||||
|
||||
/**
|
||||
* 核心线程数量
|
||||
*/
|
||||
private int corePoolSize;
|
||||
|
||||
/**
|
||||
* 最大线程数量
|
||||
*/
|
||||
private int maxPoolSize;
|
||||
|
||||
/**
|
||||
* 队列容量
|
||||
*/
|
||||
private int queueCapacity;
|
||||
|
||||
/**
|
||||
* 活跃时间
|
||||
*/
|
||||
private int keepAliveSeconds;
|
||||
|
||||
public ThreadPoolConfig() {
|
||||
this.corePoolSize = 8;
|
||||
this.maxPoolSize = 16;
|
||||
this.queueCapacity = 200;
|
||||
this.keepAliveSeconds = 300;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public enum ErrorCode implements CodeInfo {
|
||||
|
||||
BAD_REQUEST(400, "参数验证失败"),
|
||||
|
||||
UNAUTHORIZED(401, "会话过期"),
|
||||
UNAUTHORIZED(401, "当前认证信息已失效, 请重新登录"),
|
||||
|
||||
FORBIDDEN(403, "无操作权限"),
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
*/
|
||||
public class TraceIdHolder {
|
||||
|
||||
public static final String TRACE_ID_HEADER = "trace-id";
|
||||
|
||||
public static final String TRACE_ID_MDC = "tid";
|
||||
|
||||
private TraceIdHolder() {
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.orion.ops.framework.common.thread;
|
||||
|
||||
import com.orion.ops.framework.common.utils.ThreadMdcUtils;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* 自动注入 MDC 异步线程池
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/10 15:16
|
||||
*/
|
||||
public class ThreadPoolMdcTaskExecutor extends ThreadPoolTaskExecutor {
|
||||
|
||||
@Override
|
||||
public void execute(Runnable task) {
|
||||
super.execute(ThreadMdcUtils.wrap(task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
return super.submit(ThreadMdcUtils.wrap(task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<?> submit(Runnable task) {
|
||||
return super.submit(ThreadMdcUtils.wrap(task));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.orion.ops.framework.common.utils;
|
||||
|
||||
import com.orion.ops.framework.common.meta.TraceIdHolder;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* 多线程下 MDC 工具类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/10 14:55
|
||||
*/
|
||||
public class ThreadMdcUtils {
|
||||
|
||||
private ThreadMdcUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 MDC traceId
|
||||
*/
|
||||
public static void setTraceIdIfAbsent() {
|
||||
if (MDC.get(TraceIdHolder.TRACE_ID_MDC) == null) {
|
||||
MDC.put(TraceIdHolder.TRACE_ID_MDC, TraceIdHolder.get());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置线程 MDC 上下文
|
||||
*
|
||||
* @param callable callable
|
||||
* @param <T> T
|
||||
* @return callable
|
||||
*/
|
||||
public static <T> Callable<T> wrap(Callable<T> callable) {
|
||||
// 获取当前线程 MDC 上下文
|
||||
Map<String, String> callerContext = MDC.getCopyOfContextMap();
|
||||
return () -> {
|
||||
if (callerContext == null) {
|
||||
MDC.clear();
|
||||
} else {
|
||||
MDC.setContextMap(callerContext);
|
||||
}
|
||||
// 设置 traceId
|
||||
setTraceIdIfAbsent();
|
||||
// 执行线程并且清理MDC
|
||||
try {
|
||||
return callable.call();
|
||||
} finally {
|
||||
MDC.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置线程 MDC 上下文
|
||||
*
|
||||
* @param runnable runnable
|
||||
* @return callable
|
||||
*/
|
||||
public static Runnable wrap(Runnable runnable) {
|
||||
// 获取当前线程 MDC 上下文
|
||||
Map<String, String> callerContext = MDC.getCopyOfContextMap();
|
||||
return () -> {
|
||||
//
|
||||
if (callerContext == null) {
|
||||
MDC.clear();
|
||||
} else {
|
||||
MDC.setContextMap(callerContext);
|
||||
}
|
||||
// 设置 traceId
|
||||
setTraceIdIfAbsent();
|
||||
// 执行线程并且清理MDC
|
||||
try {
|
||||
runnable.run();
|
||||
} finally {
|
||||
MDC.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"groups": [
|
||||
{
|
||||
"name": "orion.thread.pool",
|
||||
"type": "com.orion.ops.framework.common.config.ThreadPoolConfig",
|
||||
"sourceType": "com.orion.ops.framework.common.config.ThreadPoolConfig"
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"name": "orion.thread.pool.core-pool-size",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "核心线程数量",
|
||||
"defaultValue": "8"
|
||||
},
|
||||
{
|
||||
"name": "orion.thread.pool.max-pool-size",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "最大线程数量.",
|
||||
"defaultValue": "16"
|
||||
},
|
||||
{
|
||||
"name": "orion.thread.pool.queue-capacity",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "队列容量.",
|
||||
"defaultValue": "200"
|
||||
},
|
||||
{
|
||||
"name": "orion.thread.pool.keep-alive-seconds",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "活跃时间.",
|
||||
"defaultValue": "300"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.orion.ops.launch.controller;
|
||||
|
||||
import com.orion.ops.framework.common.annotation.RestWrapper;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
* @version 1.0.0
|
||||
* @since 2023/6/19 17:08
|
||||
*/
|
||||
@Tag(name = "launch - 启动服务")
|
||||
@RestWrapper
|
||||
@RestController
|
||||
@RequestMapping("/server/bootstrap")
|
||||
|
||||
@@ -33,16 +33,17 @@ springdoc:
|
||||
knife4j:
|
||||
enable: false
|
||||
|
||||
logging:
|
||||
printer:
|
||||
mode: ROW
|
||||
|
||||
orion:
|
||||
logging:
|
||||
printer:
|
||||
mode: ROW
|
||||
crypto:
|
||||
aes:
|
||||
enabled: true
|
||||
working-mode: ECB
|
||||
padding-mode: PKCS5_PADDING
|
||||
# 加密秘钥
|
||||
secret-key: uQeacXV8b3isvKLK
|
||||
generator-key: true
|
||||
thread:
|
||||
pool:
|
||||
core-pool-size: 8
|
||||
max-pool-size: 16
|
||||
queue-capacity: 200
|
||||
keep-alive-seconds: 300
|
||||
|
||||
Reference in New Issue
Block a user