diff --git a/hippo4j-core/pom.xml b/hippo4j-core/pom.xml index 7b146444..0f127001 100644 --- a/hippo4j-core/pom.xml +++ b/hippo4j-core/pom.xml @@ -22,6 +22,18 @@ cn.hippo4j hippo4j-common + + + com.aliyun + alibaba-dingtalk-service-sdk + + + + log4j + log4j + + + diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/config/BootstrapPropertiesInterface.java b/hippo4j-core/src/main/java/cn/hippo4j/core/config/BootstrapPropertiesInterface.java new file mode 100644 index 00000000..ee1bc235 --- /dev/null +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/config/BootstrapPropertiesInterface.java @@ -0,0 +1,53 @@ +package cn.hippo4j.core.config; + +/** + * Bootstrap properties interface. + * + * @author chen.ma + * @date 2022/2/25 19:01 + */ +public interface BootstrapPropertiesInterface { + + /** + * Get enable. + * + * @return + */ + Boolean getEnable(); + + /** + * Get username. + * + * @return + */ + String getUsername(); + + /** + * Get password. + * + * @return + */ + String getPassword(); + + /** + * Get namespace. + * + * @return + */ + String getNamespace(); + + /** + * Get item id. + * + * @return + */ + String getItemId(); + + /** + * Get server addr. + * + * @return + */ + String getServerAddr(); + +} diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyException.java b/hippo4j-core/src/main/java/cn/hippo4j/core/config/ConfigEmptyException.java similarity index 91% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyException.java rename to hippo4j-core/src/main/java/cn/hippo4j/core/config/ConfigEmptyException.java index aaa5218a..abe84448 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyException.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/config/ConfigEmptyException.java @@ -1,4 +1,4 @@ -package cn.hippo4j.starter.core; +package cn.hippo4j.core.config; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/UtilAutoConfiguration.java b/hippo4j-core/src/main/java/cn/hippo4j/core/config/UtilAutoConfiguration.java similarity index 95% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/UtilAutoConfiguration.java rename to hippo4j-core/src/main/java/cn/hippo4j/core/config/UtilAutoConfiguration.java index 5c134ed6..45724025 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/UtilAutoConfiguration.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/config/UtilAutoConfiguration.java @@ -1,4 +1,4 @@ -package cn.hippo4j.starter.config; +package cn.hippo4j.core.config; import cn.hippo4j.core.toolkit.inet.InetUtils; import cn.hippo4j.core.toolkit.inet.InetUtilsProperties; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/BeforeCheckConfiguration.java b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/BeforeCheckConfiguration.java similarity index 95% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/BeforeCheckConfiguration.java rename to hippo4j-core/src/main/java/cn/hippo4j/core/enable/BeforeCheckConfiguration.java index bb31deaf..f269ffe0 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/BeforeCheckConfiguration.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/BeforeCheckConfiguration.java @@ -1,8 +1,8 @@ -package cn.hippo4j.starter.enable; +package cn.hippo4j.core.enable; import cn.hippo4j.common.toolkit.StringUtil; -import cn.hippo4j.starter.config.BootstrapProperties; -import cn.hippo4j.starter.core.ConfigEmptyException; +import cn.hippo4j.core.config.BootstrapPropertiesInterface; +import cn.hippo4j.core.config.ConfigEmptyException; import lombok.AllArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -20,7 +20,7 @@ import org.springframework.core.env.ConfigurableEnvironment; public class BeforeCheckConfiguration { @Bean - public BeforeCheckConfiguration.BeforeCheck dynamicThreadPoolBeforeCheckBean(@Autowired(required = false) BootstrapProperties properties, + public BeforeCheckConfiguration.BeforeCheck dynamicThreadPoolBeforeCheckBean(@Autowired(required = false) BootstrapPropertiesInterface properties, ConfigurableEnvironment environment) { if (properties != null && properties.getEnable()) { String username = properties.getUsername(); diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/EnableDynamicThreadPool.java b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/EnableDynamicThreadPool.java similarity index 91% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/EnableDynamicThreadPool.java rename to hippo4j-core/src/main/java/cn/hippo4j/core/enable/EnableDynamicThreadPool.java index 739ac226..a892a23a 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/EnableDynamicThreadPool.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/EnableDynamicThreadPool.java @@ -1,4 +1,4 @@ -package cn.hippo4j.starter.enable; +package cn.hippo4j.core.enable; import org.springframework.context.annotation.Import; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/MarkerConfiguration.java b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/MarkerConfiguration.java similarity index 91% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/MarkerConfiguration.java rename to hippo4j-core/src/main/java/cn/hippo4j/core/enable/MarkerConfiguration.java index 5d3d0da1..2daee96d 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/enable/MarkerConfiguration.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/enable/MarkerConfiguration.java @@ -1,4 +1,4 @@ -package cn.hippo4j.starter.enable; +package cn.hippo4j.core.enable; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPool.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPool.java similarity index 91% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPool.java rename to hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPool.java index 7c17d8c2..34529adc 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPool.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPool.java @@ -1,4 +1,4 @@ -package cn.hippo4j.starter.core; +package cn.hippo4j.core.executor; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java index 2d9c939b..9869e484 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java @@ -35,10 +35,10 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner @Value("${spring.profiles.active:UNKNOWN}") private String active; - @Value("${spring.dynamic.thread-pool.item-id}") + @Value("${spring.dynamic.thread-pool.item-id:}") private String itemId; - @Value("${spring.application.name}") + @Value("${spring.application.name:UNKNOWN}") private String applicationName; @Value("${spring.dynamic.thread-pool.check-state-interval:5}") @@ -107,7 +107,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId); boolean isSend = threadPoolNotifyAlarm.getIsAlarm() - && divide > threadPoolNotifyAlarm.getLivenessAlarm(); + && divide > threadPoolNotifyAlarm.getActiveAlarm(); if (isSend) { AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyReq(threadPoolExecutor); alarmNotifyRequest.setThreadPoolId(threadPoolId); @@ -123,7 +123,6 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner public void checkPoolRejectedAlarm(String threadPoolId) { ThreadPoolExecutor threadPoolExecutor = GlobalThreadPoolManage.getExecutorService(threadPoolId).getExecutor(); checkPoolRejectedAlarm(threadPoolId, threadPoolExecutor); - } /** diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java index f14cd514..c136c0e4 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalThreadPoolManage.java @@ -84,7 +84,7 @@ public class GlobalThreadPoolManage { * @return */ public static List listThreadPoolId() { - return Lists.newArrayList(POOL_PARAMETER.keySet()); + return Lists.newArrayList(EXECUTOR_MAP.keySet()); } /** diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java index 54f6afdd..1ba4a6ae 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/CommonDynamicThreadPool.java @@ -12,6 +12,12 @@ import java.util.concurrent.TimeUnit; */ public class CommonDynamicThreadPool { + /** + * Get instance. + * + * @param threadPoolId + * @return + */ public static DynamicThreadPoolExecutor getInstance(String threadPoolId) { DynamicThreadPoolExecutor poolExecutor = (DynamicThreadPoolExecutor) ThreadPoolBuilder.builder() .dynamicPool() diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java index 0552ed04..389b3fb9 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/QueueTypeEnum.java @@ -1,13 +1,14 @@ package cn.hippo4j.core.executor.support; -import cn.hippo4j.core.spi.DynamicThreadPoolServiceLoader; import cn.hippo4j.core.spi.CustomBlockingQueue; +import cn.hippo4j.core.spi.DynamicThreadPoolServiceLoader; import java.util.Arrays; import java.util.Collection; import java.util.Objects; import java.util.Optional; import java.util.concurrent.*; +import java.util.stream.Stream; /** * Queue type enum. @@ -65,6 +66,48 @@ public enum QueueTypeEnum { DynamicThreadPoolServiceLoader.register(CustomBlockingQueue.class); } + /** + * Create blocking queue. + * + * @param blockingQueueName + * @param capacity + * @return + */ + public static BlockingQueue createBlockingQueue(String blockingQueueName, Integer capacity) { + BlockingQueue blockingQueue = null; + QueueTypeEnum queueTypeEnum = Stream.of(QueueTypeEnum.values()) + .filter(each -> Objects.equals(each.name, blockingQueueName)) + .findFirst() + .orElse(null); + + if (queueTypeEnum != null) { + blockingQueue = createBlockingQueue(queueTypeEnum.type, capacity); + if (Objects.equals(blockingQueue.getClass().getSimpleName(), blockingQueueName)) { + return blockingQueue; + } + } + + Collection customBlockingQueues = DynamicThreadPoolServiceLoader + .getSingletonServiceInstances(CustomBlockingQueue.class); + blockingQueue = Optional.ofNullable(blockingQueue) + .orElseGet( + () -> customBlockingQueues.stream() + .filter(each -> Objects.equals(blockingQueueName, each.getName())) + .map(each -> each.generateBlockingQueue()) + .findFirst() + .orElseGet(() -> { + int temCapacity = capacity; + if (capacity == null || capacity <= 0) { + temCapacity = 1024; + } + + return new LinkedBlockingQueue(temCapacity); + }) + ); + + return blockingQueue; + } + /** * Create blocking queue. * diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java index 66fc0f4f..f8e995d8 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/support/RejectedTypeEnum.java @@ -21,45 +21,51 @@ public enum RejectedTypeEnum { /** * 被拒绝任务的程序由主线程执行 */ - CALLER_RUNS_POLICY(1, new ThreadPoolExecutor.CallerRunsPolicy()), + CALLER_RUNS_POLICY(1, "CallerRunsPolicy", new ThreadPoolExecutor.CallerRunsPolicy()), /** * 被拒绝任务的处理程序, 抛出异常 */ - ABORT_POLICY(2, new ThreadPoolExecutor.AbortPolicy()), + ABORT_POLICY(2, "AbortPolicy", new ThreadPoolExecutor.AbortPolicy()), /** * 被拒绝任务的处理程序, 默默地丢弃被拒绝的任务。 */ - DISCARD_POLICY(3, new ThreadPoolExecutor.DiscardPolicy()), + DISCARD_POLICY(3, "DiscardPolicy", new ThreadPoolExecutor.DiscardPolicy()), /** * 被拒绝任务的处理程序, 它丢弃最早的未处理请求, 然后重试 */ - DISCARD_OLDEST_POLICY(4, new ThreadPoolExecutor.DiscardOldestPolicy()), + DISCARD_OLDEST_POLICY(4, "DiscardOldestPolicy", new ThreadPoolExecutor.DiscardOldestPolicy()), /** * 发生拒绝事件时, 添加新任务并运行最早的任务 */ - RUNS_OLDEST_TASK_POLICY(5, new RejectedPolicies.RunsOldestTaskPolicy()), + RUNS_OLDEST_TASK_POLICY(5, "RunsOldestTaskPolicy", new RejectedPolicies.RunsOldestTaskPolicy()), /** * 使用阻塞方法将拒绝任务添加队列, 可保证任务不丢失 */ - SYNC_PUT_QUEUE_POLICY(6, new RejectedPolicies.SyncPutQueuePolicy()); + SYNC_PUT_QUEUE_POLICY(6, "SyncPutQueuePolicy", new RejectedPolicies.SyncPutQueuePolicy()); /** * 类型 */ public Integer type; + /** + * 名称 + */ + public String name; + /** * 线程池拒绝策略 */ public RejectedExecutionHandler rejectedHandler; - RejectedTypeEnum(Integer type, RejectedExecutionHandler rejectedHandler) { + RejectedTypeEnum(Integer type, String name, RejectedExecutionHandler rejectedHandler) { this.type = type; + this.name = name; this.rejectedHandler = rejectedHandler; } @@ -67,6 +73,32 @@ public enum RejectedTypeEnum { DynamicThreadPoolServiceLoader.register(CustomRejectedExecutionHandler.class); } + /** + * Create policy. + * + * @param name + * @return + */ + public static RejectedExecutionHandler createPolicy(String name) { + RejectedTypeEnum rejectedTypeEnum = Stream.of(RejectedTypeEnum.values()) + .filter(each -> Objects.equals(each.name, name)) + .findFirst() + .orElse(null); + + if (rejectedTypeEnum != null) { + return rejectedTypeEnum.rejectedHandler; + } + + Collection customRejectedExecutionHandlers = DynamicThreadPoolServiceLoader + .getSingletonServiceInstances(CustomRejectedExecutionHandler.class); + Optional customRejected = customRejectedExecutionHandlers.stream() + .filter(each -> Objects.equals(name, each.getName())) + .map(each -> each.generateRejected()) + .findFirst(); + + return customRejected.orElse(ABORT_POLICY.rejectedHandler); + } + /** * Create policy. * diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java index 37f665f0..96186138 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomBlockingQueue.java @@ -17,6 +17,15 @@ public interface CustomBlockingQueue { */ Integer getType(); + /** + * Adapt hippo4j core blocking queue. + * + * @return + */ + default String getName() { + return ""; + } + /** * Get custom blocking queue. * diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java index 1e466781..62e4e42c 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/spi/CustomRejectedExecutionHandler.java @@ -17,6 +17,15 @@ public interface CustomRejectedExecutionHandler { */ Integer getType(); + /** + * Adapt hippo4j core rejected execution handler. + * + * @return + */ + default String getName() { + return ""; + } + /** * Get custom reject policy. * diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/toolkit/DynamicThreadPoolAnnotationUtil.java b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/DynamicThreadPoolAnnotationUtil.java similarity index 98% rename from hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/toolkit/DynamicThreadPoolAnnotationUtil.java rename to hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/DynamicThreadPoolAnnotationUtil.java index 126e2783..b5f48631 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/toolkit/DynamicThreadPoolAnnotationUtil.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/DynamicThreadPoolAnnotationUtil.java @@ -1,4 +1,4 @@ -package cn.hippo4j.starter.toolkit; +package cn.hippo4j.core.toolkit.inet; import cn.hippo4j.common.config.ApplicationContextHolder; import org.springframework.beans.factory.ListableBeanFactory; diff --git a/hippo4j-example/pom.xml b/hippo4j-example/pom.xml index 58558dc1..d339916b 100644 --- a/hippo4j-example/pom.xml +++ b/hippo4j-example/pom.xml @@ -10,59 +10,17 @@ hippo4j-example - jar + pom ${project.artifactId} - Demo project for Spring Boot + ${project.artifactId} true - - - org.springframework.boot - spring-boot-starter - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-test - test - - - - cn.hippo4j - hippo4j-spring-boot-starter - ${revision} - - - - cn.hippo4j - open-change-tool - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - + + hippo4j-example-core + diff --git a/hippo4j-example/src/main/java/cn/hippo4j/example/ExampleApplication.java b/hippo4j-example/src/main/java/cn/hippo4j/example/ExampleApplication.java deleted file mode 100644 index f5095e48..00000000 --- a/hippo4j-example/src/main/java/cn/hippo4j/example/ExampleApplication.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.hippo4j.example; - -import cn.hippo4j.starter.enable.EnableDynamicThreadPool; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Example application. - * - * @author chen.ma - * @date 2022/01/23 21:06 - */ -@SpringBootApplication -@EnableDynamicThreadPool -public class ExampleApplication { - - public static void main(String[] args) { - SpringApplication.run(ExampleApplication.class, args); - } - -} diff --git a/hippo4j-example/src/main/resources/META-INF/services/cn.hippo4j.core.spi.CustomRejectedExecutionHandler b/hippo4j-example/src/main/resources/META-INF/services/cn.hippo4j.core.spi.CustomRejectedExecutionHandler deleted file mode 100644 index bdca3f76..00000000 --- a/hippo4j-example/src/main/resources/META-INF/services/cn.hippo4j.core.spi.CustomRejectedExecutionHandler +++ /dev/null @@ -1 +0,0 @@ -cn.hippo4j.example.handler.ErrorLogRejectedExecutionHandler \ No newline at end of file diff --git a/hippo4j-example/src/test/java/cn/hippo4j/example/ExampleApplication.java b/hippo4j-example/src/test/java/cn/hippo4j/example/ExampleApplication.java deleted file mode 100644 index 787cd8fc..00000000 --- a/hippo4j-example/src/test/java/cn/hippo4j/example/ExampleApplication.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.hippo4j.example; - -import lombok.extern.slf4j.Slf4j; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -/** - * Example application. - * - * @author chen.ma - * @date 2022/1/25 21:34 - */ -@Slf4j -@RunWith(SpringRunner.class) -@SpringBootTest(classes = ExampleApplication.class) -public class ExampleApplication { - - @Test - public void test() { - log.info("test success."); - } - -} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java new file mode 100644 index 00000000..6c2a7843 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/BootstrapCoreProperties.java @@ -0,0 +1,47 @@ +package cn.hippo4j.core.starter.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.List; + +/** + * Bootstrap properties. + * + * @author chen.ma + * @date 2022/2/25 00:35 + */ +@Getter +@Setter +@ConfigurationProperties(prefix = BootstrapCoreProperties.PREFIX) +public class BootstrapCoreProperties { + + public static final String PREFIX = "spring.dynamic.thread-pool"; + + /** + * Enabled banner + */ + private Boolean enableBanner; + + /*** + * Enabled collect + */ + private Boolean enabledCollect; + + /** + * Check state interval + */ + private String checkStateInterval; + + /** + * Notify platforms. + */ + private List notifyPlatforms; + + /** + * Executors + */ + private List executors; + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java new file mode 100644 index 00000000..9156c1b2 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/DynamicThreadPoolCoreAutoConfiguration.java @@ -0,0 +1,87 @@ +package cn.hippo4j.core.starter.config; + +import cn.hippo4j.common.config.ApplicationContextHolder; +import cn.hippo4j.common.notify.*; +import cn.hippo4j.common.notify.platform.DingSendMessageHandler; +import cn.hippo4j.common.notify.platform.LarkSendMessageHandler; +import cn.hippo4j.common.notify.platform.WeChatSendMessageHandler; +import cn.hippo4j.core.config.UtilAutoConfiguration; +import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; +import cn.hippo4j.core.refresh.ThreadPoolDynamicRefresh; +import cn.hippo4j.core.starter.notify.CoreNotifyConfigBuilder; +import cn.hippo4j.core.starter.support.DynamicThreadPoolPostProcessor; +import lombok.AllArgsConstructor; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; + +/** + * Dynamic thread pool auto configuration. + * + * @author chen.ma + * @date 2022/2/25 00:21 + */ +@Configuration +@AllArgsConstructor +@EnableConfigurationProperties(BootstrapCoreProperties.class) +@ImportAutoConfiguration({UtilAutoConfiguration.class}) +public class DynamicThreadPoolCoreAutoConfiguration { + + private final BootstrapCoreProperties bootstrapCoreProperties; + + @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) + public ApplicationContextHolder hippo4JApplicationContextHolder() { + return new ApplicationContextHolder(); + } + + @Bean + public AlarmControlHandler alarmControlHandler() { + return new AlarmControlHandler(); + } + + @Bean + public NotifyConfigBuilder notifyConfigBuilder(AlarmControlHandler alarmControlHandler) { + return new CoreNotifyConfigBuilder(alarmControlHandler, bootstrapCoreProperties); + } + + @Bean + public HippoSendMessageService hippoSendMessageService(NotifyConfigBuilder notifyConfigBuilder, + AlarmControlHandler alarmControlHandler) { + return new BaseSendMessageServiceImpl(notifyConfigBuilder, alarmControlHandler); + } + + @Bean + public ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler(HippoSendMessageService hippoSendMessageService) { + return new ThreadPoolNotifyAlarmHandler(hippoSendMessageService); + } + + @Bean + public SendMessageHandler dingSendMessageHandler() { + return new DingSendMessageHandler(); + } + + @Bean + public SendMessageHandler larkSendMessageHandler() { + return new LarkSendMessageHandler(); + } + + @Bean + public SendMessageHandler weChatSendMessageHandler() { + return new WeChatSendMessageHandler(); + } + + @Bean + public ThreadPoolDynamicRefresh threadPoolDynamicRefresh(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler) { + return new ThreadPoolDynamicRefresh(threadPoolNotifyAlarmHandler); + } + + @Bean + public DynamicThreadPoolPostProcessor dynamicThreadPoolPostProcessor(ApplicationContextHolder hippo4JApplicationContextHolder) { + return new DynamicThreadPoolPostProcessor(bootstrapCoreProperties); + } + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/ExecutorProperties.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/ExecutorProperties.java new file mode 100644 index 00000000..d24a9644 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/ExecutorProperties.java @@ -0,0 +1,65 @@ +package cn.hippo4j.core.starter.config; + +import cn.hippo4j.common.notify.ThreadPoolNotifyAlarm; +import lombok.Data; + +/** + * Executor properties. + * + * @author chen.ma + * @date 2022/2/25 00:40 + */ +@Data +public class ExecutorProperties { + + /** + * threadPoolId + */ + private String threadPoolId; + + /** + * corePoolSize + */ + private Integer corePoolSize; + + /** + * maximumPoolSize + */ + private Integer maximumPoolSize; + + /** + * queueCapacity + */ + private Integer queueCapacity; + + /** + * blockingQueue + */ + private String blockingQueue; + + /** + * rejectedHandler + */ + private String rejectedHandler; + + /** + * keepAliveTime + */ + private Long keepAliveTime; + + /** + * allowCoreThreadTimeOut + */ + private Boolean allowCoreThreadTimeOut; + + /** + * threadNamePrefix + */ + private String threadNamePrefix; + + /** + * Notify + */ + private ThreadPoolNotifyAlarm notify; + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/NotifyPlatformProperties.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/NotifyPlatformProperties.java new file mode 100644 index 00000000..5d560fc7 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/config/NotifyPlatformProperties.java @@ -0,0 +1,29 @@ +package cn.hippo4j.core.starter.config; + +import lombok.Data; + +/** + * Notify platform properties. + * + * @author chen.ma + * @date 2022/2/25 19:29 + */ +@Data +public class NotifyPlatformProperties { + + /** + * platform + */ + private String platform; + + /** + * secretKey + */ + private String secretKey; + + /** + * Default configuration + */ + private String receives; + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/notify/CoreNotifyConfigBuilder.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/notify/CoreNotifyConfigBuilder.java new file mode 100644 index 00000000..0c7bf603 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/notify/CoreNotifyConfigBuilder.java @@ -0,0 +1,89 @@ +package cn.hippo4j.core.starter.notify; + +import cn.hippo4j.common.notify.AlarmControlHandler; +import cn.hippo4j.common.notify.NotifyConfigBuilder; +import cn.hippo4j.common.notify.NotifyConfigDTO; +import cn.hippo4j.core.starter.config.BootstrapCoreProperties; +import cn.hippo4j.core.starter.config.ExecutorProperties; +import cn.hippo4j.core.starter.config.NotifyPlatformProperties; +import cn.hutool.core.util.StrUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.AllArgsConstructor; + +import java.util.List; +import java.util.Map; + +/** + * Core notify config builder. + * + * @author chen.ma + * @date 2022/2/25 00:24 + */ +@AllArgsConstructor +public class CoreNotifyConfigBuilder implements NotifyConfigBuilder { + + private final AlarmControlHandler alarmControlHandler; + + private final BootstrapCoreProperties bootstrapCoreProperties; + + @Override + public Map> buildNotify() { + Map> resultMap = Maps.newHashMap(); + + List executors = bootstrapCoreProperties.getExecutors(); + for (ExecutorProperties executor : executors) { + String threadPoolId = executor.getThreadPoolId(); + String alarmBuildKey = threadPoolId + "+ALARM"; + List alarmNotifyConfigs = Lists.newArrayList(); + + List notifyPlatforms = bootstrapCoreProperties.getNotifyPlatforms(); + for (NotifyPlatformProperties platformProperties : notifyPlatforms) { + NotifyConfigDTO notifyConfig = new NotifyConfigDTO(); + notifyConfig.setPlatform(platformProperties.getPlatform()); + notifyConfig.setThreadPoolId(threadPoolId); + notifyConfig.setType("ALARM"); + notifyConfig.setSecretKey(platformProperties.getSecretKey()); + notifyConfig.setInterval(executor.getNotify().getInterval()); + Map receives = executor.getNotify().getReceives(); + String receive = receives.get(platformProperties.getPlatform()); + if (StrUtil.isBlank(receive)) { + receive = platformProperties.getReceives(); + } + notifyConfig.setReceives(receive); + alarmNotifyConfigs.add(notifyConfig); + } + + resultMap.put(alarmBuildKey, alarmNotifyConfigs); + + String changeBuildKey = threadPoolId + "+CONFIG"; + List changeNotifyConfigs = Lists.newArrayList(); + + for (NotifyPlatformProperties platformProperties : notifyPlatforms) { + NotifyConfigDTO notifyConfig = new NotifyConfigDTO(); + notifyConfig.setPlatform(platformProperties.getPlatform()); + notifyConfig.setThreadPoolId(threadPoolId); + notifyConfig.setType("CONFIG"); + notifyConfig.setSecretKey(platformProperties.getSecretKey()); + + Map receives = executor.getNotify().getReceives(); + String receive = receives.get(platformProperties.getPlatform()); + if (StrUtil.isBlank(receive)) { + receive = platformProperties.getReceives(); + } + notifyConfig.setReceives(receive); + changeNotifyConfigs.add(notifyConfig); + } + + resultMap.put(changeBuildKey, changeNotifyConfigs); + } + + resultMap.forEach((key, val) -> + val.stream().filter(each -> StrUtil.equals("ALARM", each.getType())) + .forEach(each -> alarmControlHandler.initCacheAndLock(each.getThreadPoolId(), each.getPlatform(), each.getInterval())) + ); + + return resultMap; + } + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/support/DynamicThreadPoolPostProcessor.java b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/support/DynamicThreadPoolPostProcessor.java new file mode 100644 index 00000000..3fc3d7a3 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/java/cn/hippo4j/core/starter/support/DynamicThreadPoolPostProcessor.java @@ -0,0 +1,147 @@ +package cn.hippo4j.core.starter.support; + +import cn.hippo4j.common.config.ApplicationContextHolder; +import cn.hippo4j.common.notify.ThreadPoolNotifyAlarm; +import cn.hippo4j.core.executor.DynamicThreadPool; +import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; +import cn.hippo4j.core.executor.DynamicThreadPoolWrapper; +import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage; +import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; +import cn.hippo4j.core.executor.support.*; +import cn.hippo4j.core.starter.config.BootstrapCoreProperties; +import cn.hippo4j.core.starter.config.ExecutorProperties; +import cn.hippo4j.core.toolkit.inet.DynamicThreadPoolAnnotationUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.core.task.TaskDecorator; + +import java.util.Objects; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Dynamic threadPool post processor. + * + * @author chen.ma + * @date 2021/8/2 20:40 + */ +@Slf4j +@AllArgsConstructor +public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor { + + private final BootstrapCoreProperties bootstrapCoreProperties; + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof DynamicThreadPoolExecutor) { + DynamicThreadPool dynamicThreadPool; + try { + dynamicThreadPool = ApplicationContextHolder.findAnnotationOnBean(beanName, DynamicThreadPool.class); + if (Objects.isNull(dynamicThreadPool)) { + // 适配低版本 SpringBoot + dynamicThreadPool = DynamicThreadPoolAnnotationUtil.findAnnotationOnBean(beanName, DynamicThreadPool.class); + if (Objects.isNull(dynamicThreadPool)) { + return bean; + } + } + } catch (Exception ex) { + log.error("Failed to create dynamic thread pool in annotation mode.", ex); + return bean; + } + + DynamicThreadPoolExecutor dynamicExecutor = (DynamicThreadPoolExecutor) bean; + DynamicThreadPoolWrapper wrap = new DynamicThreadPoolWrapper(dynamicExecutor.getThreadPoolId(), dynamicExecutor); + ThreadPoolExecutor remoteExecutor = fillPoolAndRegister(wrap); + return remoteExecutor; + } + + if (bean instanceof DynamicThreadPoolWrapper) { + DynamicThreadPoolWrapper wrap = (DynamicThreadPoolWrapper) bean; + registerAndSubscribe(wrap); + } + + return bean; + } + + /** + * Register and subscribe. + * + * @param dynamicThreadPoolWrap + */ + protected void registerAndSubscribe(DynamicThreadPoolWrapper dynamicThreadPoolWrap) { + fillPoolAndRegister(dynamicThreadPoolWrap); + } + + /** + * Fill the thread pool and register. + * + * @param dynamicThreadPoolWrap + */ + protected ThreadPoolExecutor fillPoolAndRegister(DynamicThreadPoolWrapper dynamicThreadPoolWrap) { + String threadPoolId = dynamicThreadPoolWrap.getTpId(); + ThreadPoolExecutor newDynamicPoolExecutor = dynamicThreadPoolWrap.getExecutor(); + + ExecutorProperties executorProperties = bootstrapCoreProperties.getExecutors() + .stream() + .filter(each -> Objects.equals(threadPoolId, each.getThreadPoolId())) + .findFirst() + .orElse(null); + if (executorProperties != null) { + try { + // 使用相关参数创建线程池 + BlockingQueue workQueue = QueueTypeEnum.createBlockingQueue(executorProperties.getBlockingQueue(), executorProperties.getQueueCapacity()); + newDynamicPoolExecutor = ThreadPoolBuilder.builder() + .dynamicPool() + .workQueue(workQueue) + .threadFactory(threadPoolId) + .poolThreadSize(executorProperties.getCorePoolSize(), executorProperties.getMaximumPoolSize()) + .keepAliveTime(executorProperties.getKeepAliveTime(), TimeUnit.SECONDS) + .rejected(RejectedTypeEnum.createPolicy(executorProperties.getRejectedHandler())) + .allowCoreThreadTimeOut(executorProperties.getAllowCoreThreadTimeOut()) + .build(); + + // 设置动态线程池增强参数 + ThreadPoolNotifyAlarm notify = executorProperties.getNotify(); + if (dynamicThreadPoolWrap.getExecutor() instanceof AbstractDynamicExecutorSupport) { + ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm( + notify.getIsAlarm(), + notify.getCapacityAlarm(), + notify.getActiveAlarm() + ); + + threadPoolNotifyAlarm.setInterval(notify.getInterval()); + threadPoolNotifyAlarm.setReceives(notify.getReceives()); + GlobalNotifyAlarmManage.put(threadPoolId, threadPoolNotifyAlarm); + + TaskDecorator taskDecorator = ((DynamicThreadPoolExecutor) dynamicThreadPoolWrap.getExecutor()).getTaskDecorator(); + ((DynamicThreadPoolExecutor) newDynamicPoolExecutor).setTaskDecorator(taskDecorator); + + long awaitTerminationMillis = ((DynamicThreadPoolExecutor) dynamicThreadPoolWrap.getExecutor()).awaitTerminationMillis; + boolean waitForTasksToCompleteOnShutdown = ((DynamicThreadPoolExecutor) dynamicThreadPoolWrap.getExecutor()).waitForTasksToCompleteOnShutdown; + ((DynamicThreadPoolExecutor) newDynamicPoolExecutor).setSupportParam(awaitTerminationMillis, waitForTasksToCompleteOnShutdown); + } + + dynamicThreadPoolWrap.setExecutor(newDynamicPoolExecutor); + } catch (Exception ex) { + log.error("Failed to initialize thread pool configuration. error message :: {}", ex.getMessage()); + } finally { + if (Objects.isNull(dynamicThreadPoolWrap.getExecutor())) { + dynamicThreadPoolWrap.setExecutor(CommonDynamicThreadPool.getInstance(threadPoolId)); + } + } + + GlobalThreadPoolManage.registerPool(dynamicThreadPoolWrap.getTpId(), dynamicThreadPoolWrap); + } + + return newDynamicPoolExecutor; + } + +} diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/LICENSE b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/LICENSE new file mode 100644 index 00000000..ff773796 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/spring.factories b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..6b409eb7 --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-core-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hippo4j.core.starter.config.DynamicThreadPoolCoreAutoConfiguration diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java index 0ca29d8e..76cb7c16 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/BootstrapProperties.java @@ -1,5 +1,6 @@ package cn.hippo4j.starter.config; +import cn.hippo4j.core.config.BootstrapPropertiesInterface; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -15,7 +16,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @Getter @Setter @ConfigurationProperties(prefix = BootstrapProperties.PREFIX) -public class BootstrapProperties { +public class BootstrapProperties implements BootstrapPropertiesInterface { public static final String PREFIX = "spring.dynamic.thread-pool"; @@ -52,7 +53,7 @@ public class BootstrapProperties { /** * Print dynamic thread pool banner */ - private Boolean banner = true; + private Boolean enableBanner = true; /** * Enable client data collect diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java index 215a2e7d..7ff48524 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/config/DynamicThreadPoolAutoConfiguration.java @@ -2,6 +2,7 @@ package cn.hippo4j.starter.config; import cn.hippo4j.common.api.ThreadDetailState; import cn.hippo4j.common.config.ApplicationContextHolder; +import cn.hippo4j.core.config.UtilAutoConfiguration; import cn.hippo4j.core.refresh.ThreadPoolDynamicRefresh; import cn.hippo4j.core.toolkit.IdentifyUtil; import cn.hippo4j.core.toolkit.inet.InetUtils; @@ -11,7 +12,7 @@ import cn.hippo4j.starter.core.ConfigService; import cn.hippo4j.starter.core.DynamicThreadPoolPostProcessor; import cn.hippo4j.starter.core.ThreadPoolConfigService; import cn.hippo4j.starter.core.ThreadPoolOperation; -import cn.hippo4j.starter.enable.MarkerConfiguration; +import cn.hippo4j.core.enable.MarkerConfiguration; import cn.hippo4j.starter.event.ApplicationContentPostProcessor; import cn.hippo4j.starter.handler.BaseThreadDetailStateHandler; import cn.hippo4j.starter.handler.DynamicThreadPoolBannerHandler; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java index 9349b267..55b9c47b 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/ConfigEmptyAnalyzer.java @@ -1,5 +1,6 @@ package cn.hippo4j.starter.core; +import cn.hippo4j.core.config.ConfigEmptyException; import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; import org.springframework.boot.diagnostics.FailureAnalysis; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java index 09fc30e9..bd7dca8c 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/core/DynamicThreadPoolPostProcessor.java @@ -7,6 +7,7 @@ import cn.hippo4j.common.model.PoolParameterInfo; import cn.hippo4j.common.notify.ThreadPoolNotifyAlarm; import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.web.base.Result; +import cn.hippo4j.core.executor.DynamicThreadPool; import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; import cn.hippo4j.core.executor.DynamicThreadPoolWrapper; import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage; @@ -15,7 +16,7 @@ import cn.hippo4j.core.executor.support.*; import cn.hippo4j.core.refresh.ThreadPoolDynamicRefresh; import cn.hippo4j.starter.config.BootstrapProperties; import cn.hippo4j.starter.remote.HttpAgent; -import cn.hippo4j.starter.toolkit.DynamicThreadPoolAnnotationUtil; +import cn.hippo4j.core.toolkit.inet.DynamicThreadPoolAnnotationUtil; import cn.hutool.core.util.BooleanUtil; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java index 43baf497..818ff602 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/starter/handler/DynamicThreadPoolBannerHandler.java @@ -42,7 +42,7 @@ public class DynamicThreadPoolBannerHandler implements InitializingBean { "|___/ \\_, |_||_\\__,_|_|_|_|_\\__| |_| |_| \n" + " |__/ \n"; - if (properties.getBanner()) { + if (properties.getEnableBanner()) { String version = getVersion(); version = (version != null) ? " (v" + version + ")" : "no version."; diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/alarm.json b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/alarm.json deleted file mode 100644 index 23af7381..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/alarm.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "msg_type": "interactive", - "card": { - "config": { - "wide_screen_mode": true - }, - "header": { - "template": "red", - "title": { - "content": "[🔥警报] %s 动态线程池运行告警", - "tag": "plain_text" - } - }, - "elements": [ - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** 线程池ID:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 应用名称:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 应用实例:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 报警类型:** %s", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** 核心线程数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 最大线程数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 当前线程数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 活跃线程数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 最大任务数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 线程池任务总量:** %s", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** 队列类型:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 队列容量:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 队列元素个数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 队列剩余个数:** %s", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** 拒绝策略:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 拒绝策略执行次数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** OWNER:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 播报时间: ** %s", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "tag": "note", - "elements": [ - { - "tag": "plain_text", - "content": "提示: %s 分钟内此线程池不会重复告警(可配置)" - } - ] - } - ] - } -} - diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/notice.json b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/notice.json deleted file mode 100644 index 9d85622e..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/resources/properties/lark/notice.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "msg_type": "interactive", - "card": { - - "config": { - "wide_screen_mode": true - }, - "header": { - "template": "greed", - "title": { - "content": "[通知] %s 动态线程池参数变更", - "tag": "plain_text" - } - }, - "elements": [ - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** 线程池ID:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 应用名称:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 应用实例:** %s", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** 核心线程数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 最大线程数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 核心线程超时:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 线程存活时间:** %s / SECONDS", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** 队列类型:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 队列容量:** %s", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "fields": [ - { - "is_short": true, - "text": { - "content": "** AGO 拒绝策略:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** NOW 拒绝策略执行次数:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** OWNER:** %s", - "tag": "lark_md" - } - }, - { - "is_short": true, - "text": { - "content": "** 播报时间: ** %s", - "tag": "lark_md" - } - } - ], - "tag": "div" - }, - { - "tag": "hr" - }, - { - "tag": "note", - "elements": [ - { - "tag": "plain_text", - "content": "提示:动态线程池配置变更实时通知(无限制)" - } - ] - } - ] - } -}