Merge pull request #421 from mabaiwan/develop

Dynamic thread pool monitoring module refactoring (#361) (#386)
pull/436/head
小马哥 2 years ago committed by GitHub
commit b9d001ab09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -18,7 +18,7 @@ spring.cloud.nacos.config.extension-configs[0].refresh=true
spring.dynamic.thread-pool.enable=true spring.dynamic.thread-pool.enable=true
spring.dynamic.thread-pool.banner=true spring.dynamic.thread-pool.banner=true
spring.dynamic.thread-pool.collect=true spring.dynamic.thread-pool.collect=true
spring.dynamic.thread-pool.collect-type=metric spring.dynamic.thread-pool.collect-type=log,prometheus
spring.dynamic.thread-pool.check-state-interval=5 spring.dynamic.thread-pool.check-state-interval=5
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-monitor</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hippo4j-monitor-base</artifactId>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-core</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.json</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Implementation-Title>${project.artifactId}</Implementation-Title>
<Implementation-Version>${project.version}</Implementation-Version>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Built-By>chen.ma</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package cn.hippo4j.core.springboot.starter.monitor; package com.example.monitor.base;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo; import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
@ -26,9 +26,6 @@ import java.util.List;
/** /**
* Abstract dynamic thread-pool monitor. * Abstract dynamic thread-pool monitor.
*
* @author chen.ma
* @date 2022/3/25 12:07
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
public abstract class AbstractDynamicThreadPoolMonitor implements DynamicThreadPoolMonitor { public abstract class AbstractDynamicThreadPoolMonitor implements DynamicThreadPoolMonitor {
@ -36,7 +33,7 @@ public abstract class AbstractDynamicThreadPoolMonitor implements DynamicThreadP
private final ThreadPoolRunStateHandler threadPoolRunStateHandler; private final ThreadPoolRunStateHandler threadPoolRunStateHandler;
/** /**
* Execute. * Execute collection thread pool running data.
* *
* @param poolRunStateInfo * @param poolRunStateInfo
*/ */

@ -15,13 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
package cn.hippo4j.core.springboot.starter.monitor; package com.example.monitor.base;
/** /**
* Dynamic thread-pool monitor. * Dynamic thread-pool monitor.
*
* @author chen.ma
* @date 2022/3/25 19:03
*/ */
public interface DynamicThreadPoolMonitor extends ThreadPoolMonitor { public interface DynamicThreadPoolMonitor extends ThreadPoolMonitor {

@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
package com.example.monitor.base;
/**
* Monitor type enum.
*/
public enum MonitorTypeEnum {
LOG, PROMETHEUS, SERVER
}

@ -15,13 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
package cn.hippo4j.core.springboot.starter.monitor; package com.example.monitor.base;
/** /**
* Thread-pool monitor. * Thread-pool monitor.
*
* @author chen.ma
* @date 2022/3/25 19:03
*/ */
public interface ThreadPoolMonitor { public interface ThreadPoolMonitor {

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-monitor</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hippo4j-monitor-log</artifactId>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-monitor-base</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.json</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Implementation-Title>${project.artifactId}</Implementation-Title>
<Implementation-Version>${project.version}</Implementation-Version>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Built-By>chen.ma</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -15,18 +15,16 @@
* limitations under the License. * limitations under the License.
*/ */
package cn.hippo4j.core.springboot.starter.monitor; package cn.hippo4j.monitor.log;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo; import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler; import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import com.example.monitor.base.AbstractDynamicThreadPoolMonitor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**
* Log monitor handler. * Log monitor handler
*
* @author chen.ma
* @date 2022/3/25 19:22
*/ */
@Slf4j @Slf4j
public class LogMonitorHandler extends AbstractDynamicThreadPoolMonitor { public class LogMonitorHandler extends AbstractDynamicThreadPoolMonitor {

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-monitor</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hippo4j-monitor-prometheus</artifactId>
<dependencies>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-monitor-base</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>${micrometer-core.version}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.json</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Implementation-Title>${project.artifactId}</Implementation-Title>
<Implementation-Version>${project.version}</Implementation-Version>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Built-By>chen.ma</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -15,12 +15,13 @@
* limitations under the License. * limitations under the License.
*/ */
package cn.hippo4j.core.springboot.starter.monitor; package cn.hippo4j.monitor.prometheus;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo; import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler; import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.example.monitor.base.AbstractDynamicThreadPoolMonitor;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Metrics;
@ -30,12 +31,9 @@ import org.springframework.core.env.Environment;
import java.util.Map; import java.util.Map;
/** /**
* Metric monitor handler. * Prometheus monitor handler.
*
* @author chen.ma
* @date 2022/3/25 20:37
*/ */
public class MetricMonitorHandler extends AbstractDynamicThreadPoolMonitor { public class PrometheusMonitorHandler extends AbstractDynamicThreadPoolMonitor {
private final static String METRIC_NAME_PREFIX = "dynamic.thread-pool"; private final static String METRIC_NAME_PREFIX = "dynamic.thread-pool";
@ -45,7 +43,7 @@ public class MetricMonitorHandler extends AbstractDynamicThreadPoolMonitor {
private final Map<String, ThreadPoolRunStateInfo> RUN_STATE_CACHE = Maps.newConcurrentMap(); private final Map<String, ThreadPoolRunStateInfo> RUN_STATE_CACHE = Maps.newConcurrentMap();
public MetricMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) { public PrometheusMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
super(threadPoolRunStateHandler); super(threadPoolRunStateHandler);
} }
@ -57,13 +55,11 @@ public class MetricMonitorHandler extends AbstractDynamicThreadPoolMonitor {
} else { } else {
BeanUtil.copyProperties(poolRunStateInfo, stateInfo); BeanUtil.copyProperties(poolRunStateInfo, stateInfo);
} }
Environment environment = ApplicationContextHolder.getInstance().getEnvironment(); Environment environment = ApplicationContextHolder.getInstance().getEnvironment();
String applicationName = environment.getProperty("spring.application.name", "application"); String applicationName = environment.getProperty("spring.application.name", "application");
Iterable<Tag> tags = Lists.newArrayList( Iterable<Tag> tags = Lists.newArrayList(
Tag.of(DYNAMIC_THREAD_POOL_ID_TAG, poolRunStateInfo.getTpId()), Tag.of(DYNAMIC_THREAD_POOL_ID_TAG, poolRunStateInfo.getTpId()),
Tag.of(APPLICATION_NAME_TAG, applicationName)); Tag.of(APPLICATION_NAME_TAG, applicationName));
// load // load
Metrics.gauge(metricName("current.load"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getSimpleCurrentLoad); Metrics.gauge(metricName("current.load"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getSimpleCurrentLoad);
Metrics.gauge(metricName("peak.load"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getSimplePeakLoad); Metrics.gauge(metricName("peak.load"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getSimplePeakLoad);
@ -88,6 +84,6 @@ public class MetricMonitorHandler extends AbstractDynamicThreadPoolMonitor {
@Override @Override
public String getType() { public String getType() {
return "metric"; return "prometheus";
} }
} }

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-all</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hippo4j-monitor</artifactId>
<packaging>pom</packaging>
<modules>
<module>hippo4j-monitor-base</module>
<module>hippo4j-monitor-log</module>
<module>hippo4j-monitor-prometheus</module>
</modules>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.json</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Implementation-Title>${project.artifactId}</Implementation-Title>
<Implementation-Version>${project.version}</Implementation-Version>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Built-By>chen.ma</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -63,20 +63,25 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.micrometer</groupId> <groupId>cn.hippo4j</groupId>
<artifactId>micrometer-core</artifactId> <artifactId>hippo4j-adapter-base</artifactId>
<version>${micrometer-core.version}</version>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.hippo4j</groupId> <groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-adapter-base</artifactId> <artifactId>hippo4j-spring-boot-starter-adapter-web</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.hippo4j</groupId> <groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter-adapter-web</artifactId> <artifactId>hippo4j-monitor-log</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-monitor-prometheus</artifactId>
<version>${revision}</version>
</dependency> </dependency>
</dependencies> </dependencies>

@ -18,8 +18,8 @@
package cn.hippo4j.core.springboot.starter.config; package cn.hippo4j.core.springboot.starter.config;
import cn.hippo4j.core.config.BootstrapPropertiesInterface; import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import cn.hippo4j.core.springboot.starter.monitor.DynamicThreadPoolMonitor;
import cn.hippo4j.core.springboot.starter.parser.ConfigFileTypeEnum; import cn.hippo4j.core.springboot.starter.parser.ConfigFileTypeEnum;
import com.example.monitor.base.DynamicThreadPoolMonitor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -56,7 +56,7 @@ public class BootstrapCoreProperties implements BootstrapPropertiesInterface {
private Boolean collect = Boolean.TRUE; private Boolean collect = Boolean.TRUE;
/** /**
* Type of collection thread pool running data. eg: log,metric. Multiple can be used at the same time. * Type of collection thread pool running data. eg: log,prometheus. Multiple can be used at the same time.
* Custom SPI support {@link DynamicThreadPoolMonitor}. * Custom SPI support {@link DynamicThreadPoolMonitor}.
*/ */
private String collectType; private String collectType;

@ -21,11 +21,8 @@ import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.core.config.UtilAutoConfiguration; import cn.hippo4j.core.config.UtilAutoConfiguration;
import cn.hippo4j.core.enable.MarkerConfiguration; import cn.hippo4j.core.enable.MarkerConfiguration;
import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.core.handler.DynamicThreadPoolBannerHandler; import cn.hippo4j.core.handler.DynamicThreadPoolBannerHandler;
import cn.hippo4j.core.springboot.starter.monitor.DynamicThreadPoolMonitorExecutor; import cn.hippo4j.core.springboot.starter.monitor.DynamicThreadPoolMonitorExecutor;
import cn.hippo4j.core.springboot.starter.monitor.LogMonitorHandler;
import cn.hippo4j.core.springboot.starter.monitor.MetricMonitorHandler;
import cn.hippo4j.core.springboot.starter.notify.CoreNotifyConfigBuilder; import cn.hippo4j.core.springboot.starter.notify.CoreNotifyConfigBuilder;
import cn.hippo4j.core.springboot.starter.refresher.event.AdapterExecutorsListener; import cn.hippo4j.core.springboot.starter.refresher.event.AdapterExecutorsListener;
import cn.hippo4j.core.springboot.starter.refresher.event.ExecutorsListener; import cn.hippo4j.core.springboot.starter.refresher.event.ExecutorsListener;
@ -51,10 +48,7 @@ import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
/** /**
* Dynamic thread-pool auto configuration. * Dynamic thread-pool core auto-configuration.
*
* @author chen.ma
* @date 2022/2/25 00:21
*/ */
@Configuration @Configuration
@AllArgsConstructor @AllArgsConstructor
@ -64,7 +58,8 @@ import org.springframework.core.annotation.Order;
@ConditionalOnProperty(prefix = BootstrapCoreProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true") @ConditionalOnProperty(prefix = BootstrapCoreProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true")
@Import({ @Import({
ConfigHandlerConfiguration.EmbeddedNacos.class, ConfigHandlerConfiguration.EmbeddedNacosCloud.class, ConfigHandlerConfiguration.EmbeddedNacos.class, ConfigHandlerConfiguration.EmbeddedNacosCloud.class,
ConfigHandlerConfiguration.EmbeddedApollo.class, ConfigHandlerConfiguration.EmbeddedZookeeper.class ConfigHandlerConfiguration.EmbeddedApollo.class, ConfigHandlerConfiguration.EmbeddedZookeeper.class,
MonitorHandlerConfiguration.EmbeddedLogMonitor.class, MonitorHandlerConfiguration.EmbeddedPrometheusMonitor.class
}) })
public class DynamicThreadPoolCoreAutoConfiguration { public class DynamicThreadPoolCoreAutoConfiguration {
@ -97,16 +92,6 @@ public class DynamicThreadPoolCoreAutoConfiguration {
return new DynamicThreadPoolMonitorExecutor(bootstrapCoreProperties); return new DynamicThreadPoolMonitorExecutor(bootstrapCoreProperties);
} }
@Bean
public LogMonitorHandler hippo4jLogMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new LogMonitorHandler(threadPoolRunStateHandler);
}
@Bean
public MetricMonitorHandler hippo4jMetricMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new MetricMonitorHandler(threadPoolRunStateHandler);
}
@Bean @Bean
@SuppressWarnings("all") @SuppressWarnings("all")
public ExecutorsListener hippo4jExecutorsListener(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler, public ExecutorsListener hippo4jExecutorsListener(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler,

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
package cn.hippo4j.core.springboot.starter.config;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.core.springboot.starter.config.condition.LogMonitorCondition;
import cn.hippo4j.core.springboot.starter.config.condition.PrometheusMonitorCondition;
import cn.hippo4j.monitor.log.LogMonitorHandler;
import cn.hippo4j.monitor.prometheus.PrometheusMonitorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
/**
* Monitor handler configuration.
*/
@Configuration(proxyBeanMethods = false)
public class MonitorHandlerConfiguration {
@Conditional(LogMonitorCondition.class)
static class EmbeddedLogMonitor {
@Bean
public LogMonitorHandler logMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new LogMonitorHandler(threadPoolRunStateHandler);
}
}
@Conditional(PrometheusMonitorCondition.class)
static class EmbeddedPrometheusMonitor {
@Bean
public PrometheusMonitorHandler prometheusMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new PrometheusMonitorHandler(threadPoolRunStateHandler);
}
}
}

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
package cn.hippo4j.core.springboot.starter.config.condition;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.springboot.starter.config.BootstrapCoreProperties;
import com.example.monitor.base.MonitorTypeEnum;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* Log monitor condition.
*/
public class LogMonitorCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String collectType = context.getEnvironment().getProperty(BootstrapCoreProperties.PREFIX + ".collect-type", "");
return StringUtil.isNotEmpty(collectType) && collectType.contains(MonitorTypeEnum.LOG.name().toLowerCase()) ? true : false;
}
}

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
package cn.hippo4j.core.springboot.starter.config.condition;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.springboot.starter.config.BootstrapCoreProperties;
import com.example.monitor.base.MonitorTypeEnum;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* Prometheus monitor condition.
*/
public class PrometheusMonitorCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String collectType = context.getEnvironment().getProperty(BootstrapCoreProperties.PREFIX + "collect-type", "");
return StringUtil.isNotEmpty(collectType) && collectType.contains(MonitorTypeEnum.PROMETHEUS.name().toLowerCase()) ? true : false;
}
}

@ -22,6 +22,8 @@ import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.executor.support.ThreadFactoryBuilder; import cn.hippo4j.core.executor.support.ThreadFactoryBuilder;
import cn.hippo4j.core.spi.DynamicThreadPoolServiceLoader; import cn.hippo4j.core.spi.DynamicThreadPoolServiceLoader;
import cn.hippo4j.core.springboot.starter.config.BootstrapCoreProperties; import cn.hippo4j.core.springboot.starter.config.BootstrapCoreProperties;
import com.example.monitor.base.DynamicThreadPoolMonitor;
import com.example.monitor.base.ThreadPoolMonitor;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -56,15 +58,11 @@ public class DynamicThreadPoolMonitorExecutor implements ApplicationRunner {
if (!properties.getCollect() || StringUtil.isBlank(collectType)) { if (!properties.getCollect() || StringUtil.isBlank(collectType)) {
return; return;
} }
log.info("Start monitoring the running status of dynamic thread pool."); log.info("Start monitoring the running status of dynamic thread pool.");
threadPoolMonitors = Lists.newArrayList(); threadPoolMonitors = Lists.newArrayList();
String collectTaskName = "client.scheduled.collect.data";
collectExecutor = new ScheduledThreadPoolExecutor( collectExecutor = new ScheduledThreadPoolExecutor(
new Integer(1), new Integer(1),
ThreadFactoryBuilder.builder().daemon(true).prefix(collectTaskName).build()); ThreadFactoryBuilder.builder().daemon(true).prefix("client.scheduled.collect.data").build());
// Get dynamic thread pool monitoring component. // Get dynamic thread pool monitoring component.
List<String> collectTypes = Arrays.asList(collectType.split(",")); List<String> collectTypes = Arrays.asList(collectType.split(","));
ApplicationContextHolder.getBeansOfType(ThreadPoolMonitor.class) ApplicationContextHolder.getBeansOfType(ThreadPoolMonitor.class)
@ -76,7 +74,6 @@ public class DynamicThreadPoolMonitorExecutor implements ApplicationRunner {
Collection<DynamicThreadPoolMonitor> dynamicThreadPoolMonitors = Collection<DynamicThreadPoolMonitor> dynamicThreadPoolMonitors =
DynamicThreadPoolServiceLoader.getSingletonServiceInstances(DynamicThreadPoolMonitor.class); DynamicThreadPoolServiceLoader.getSingletonServiceInstances(DynamicThreadPoolMonitor.class);
dynamicThreadPoolMonitors.stream().filter(each -> collectTypes.contains(each.getType())).forEach(each -> threadPoolMonitors.add(each)); dynamicThreadPoolMonitors.stream().filter(each -> collectTypes.contains(each.getType())).forEach(each -> threadPoolMonitors.add(each));
// Execute dynamic thread pool monitoring component. // Execute dynamic thread pool monitoring component.
collectExecutor.scheduleWithFixedDelay( collectExecutor.scheduleWithFixedDelay(
() -> scheduleRunnable(), () -> scheduleRunnable(),

@ -96,6 +96,12 @@
<groupId>cn.hippo4j</groupId> <groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter-adapter-web</artifactId> <artifactId>hippo4j-spring-boot-starter-adapter-web</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-monitor-prometheus</artifactId>
<version>${revision}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -18,6 +18,7 @@
package cn.hippo4j.springboot.starter.config; package cn.hippo4j.springboot.starter.config;
import cn.hippo4j.core.config.BootstrapPropertiesInterface; import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import com.example.monitor.base.DynamicThreadPoolMonitor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -61,6 +62,7 @@ public class BootstrapProperties implements BootstrapPropertiesInterface {
* Report type * Report type
*/ */
private String reportType; private String reportType;
/** /**
* Namespace * Namespace
*/ */
@ -86,6 +88,12 @@ public class BootstrapProperties implements BootstrapPropertiesInterface {
*/ */
private Boolean collect = true; private Boolean collect = true;
/**
* Type of collection thread pool running data. eg: server,prometheus. Multiple can be used at the same time.
* Custom SPI support {@link DynamicThreadPoolMonitor}.
*/
private String collectType;
/** /**
* Task buffer container capacity * Task buffer container capacity
*/ */

@ -53,6 +53,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
@ -69,6 +70,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
@EnableConfigurationProperties(BootstrapProperties.class) @EnableConfigurationProperties(BootstrapProperties.class)
@ConditionalOnProperty(prefix = BootstrapProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true") @ConditionalOnProperty(prefix = BootstrapProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true")
@ImportAutoConfiguration({HttpClientConfiguration.class, NettyClientConfiguration.class, DiscoveryConfiguration.class, MessageConfiguration.class, UtilAutoConfiguration.class}) @ImportAutoConfiguration({HttpClientConfiguration.class, NettyClientConfiguration.class, DiscoveryConfiguration.class, MessageConfiguration.class, UtilAutoConfiguration.class})
@Import(MonitorHandlerConfiguration.EmbeddedPrometheusMonitor.class)
public class DynamicThreadPoolAutoConfiguration { public class DynamicThreadPoolAutoConfiguration {
private final BootstrapProperties properties; private final BootstrapProperties properties;

@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
package cn.hippo4j.springboot.starter.config;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.monitor.prometheus.PrometheusMonitorHandler;
import cn.hippo4j.springboot.starter.config.condition.PrometheusMonitorCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
/**
* Monitor handler configuration.
*/
@Configuration(proxyBeanMethods = false)
public class MonitorHandlerConfiguration {
@Conditional(PrometheusMonitorCondition.class)
static class EmbeddedPrometheusMonitor {
@Bean
public PrometheusMonitorHandler prometheusMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new PrometheusMonitorHandler(threadPoolRunStateHandler);
}
}
}

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
package cn.hippo4j.springboot.starter.config.condition;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.springboot.starter.config.BootstrapProperties;
import com.example.monitor.base.MonitorTypeEnum;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* Prometheus monitor condition.
*/
public class PrometheusMonitorCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String collectType = context.getEnvironment().getProperty(BootstrapProperties.PREFIX + ".collect-type", "");
return StringUtil.isNotEmpty(collectType) && collectType.contains(MonitorTypeEnum.PROMETHEUS.name().toLowerCase()) ? true : false;
}
}

@ -19,13 +19,17 @@ package cn.hippo4j.springboot.starter.monitor;
import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.monitor.Message; import cn.hippo4j.common.monitor.Message;
import cn.hippo4j.common.toolkit.ThreadUtil;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.core.executor.support.ThreadFactoryBuilder;
import cn.hippo4j.springboot.starter.config.BootstrapProperties; import cn.hippo4j.springboot.starter.config.BootstrapProperties;
import cn.hippo4j.springboot.starter.monitor.collect.Collector; import cn.hippo4j.springboot.starter.monitor.collect.Collector;
import cn.hippo4j.springboot.starter.remote.ServerHealthCheck;
import cn.hippo4j.springboot.starter.monitor.send.MessageSender; import cn.hippo4j.springboot.starter.monitor.send.MessageSender;
import cn.hippo4j.core.executor.support.ThreadFactoryBuilder; import cn.hippo4j.springboot.starter.remote.ServerHealthCheck;
import cn.hippo4j.common.toolkit.ThreadUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.example.monitor.base.MonitorTypeEnum;
import com.example.monitor.base.ThreadPoolMonitor;
import com.google.common.base.Strings;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@ -68,6 +72,11 @@ public class ReportingEventExecutor implements Runnable, CommandLineRunner, Disp
*/ */
private Map<String, Collector> collectors; private Map<String, Collector> collectors;
/**
* Thread pool monitoring collection.
*/
private Map<String, ThreadPoolMonitor> threadPoolMonitors;
/** /**
* Buffer container for data collection, waiting * Buffer container for data collection, waiting
* for ReportingEventExecutor to report to the server. * for ReportingEventExecutor to report to the server.
@ -95,25 +104,39 @@ public class ReportingEventExecutor implements Runnable, CommandLineRunner, Disp
@Override @Override
public void run(String... args) { public void run(String... args) {
if (properties.getCollect()) { if (!properties.getCollect()) {
Integer bufferSize = properties.getTaskBufferSize(); return;
messageCollectVessel = new ArrayBlockingQueue(bufferSize); }
String collectVesselTaskName = "client.scheduled.collect.data"; String collectType = Optional.ofNullable(Strings.emptyToNull(properties.getCollectType())).orElse(MonitorTypeEnum.SERVER.name().toLowerCase());
collectVesselExecutor = new ScheduledThreadPoolExecutor( collectVesselExecutor = new ScheduledThreadPoolExecutor(
new Integer(1), new Integer(collectType.split(",").length),
ThreadFactoryBuilder.builder().daemon(true).prefix(collectVesselTaskName).build()); ThreadFactoryBuilder.builder().daemon(true).prefix("client.scheduled.collect.data").build());
if (collectType.contains(MonitorTypeEnum.PROMETHEUS.name().toLowerCase())
|| collectType.contains(MonitorTypeEnum.LOG.name().toLowerCase())) {
// Get all dynamic thread pool monitoring components.
threadPoolMonitors = ApplicationContextHolder.getBeansOfType(ThreadPoolMonitor.class);
collectVesselExecutor.scheduleWithFixedDelay(
() -> dynamicThreadPoolMonitor(),
properties.getInitialDelay(),
properties.getCollectInterval(),
TimeUnit.MILLISECONDS);
}
if (collectType.contains(MonitorTypeEnum.SERVER.name().toLowerCase())) {
collectVesselExecutor.scheduleWithFixedDelay( collectVesselExecutor.scheduleWithFixedDelay(
() -> runTimeGatherTask(), () -> runTimeGatherTask(),
properties.getInitialDelay(), properties.getInitialDelay(),
properties.getCollectInterval(), properties.getCollectInterval(),
TimeUnit.MILLISECONDS); TimeUnit.MILLISECONDS);
// Start reporting monitoring data thread Integer bufferSize = properties.getTaskBufferSize();
String reportingTaskName = "client.thread.reporting.task"; messageCollectVessel = new ArrayBlockingQueue(bufferSize);
ThreadUtil.newThread(this, reportingTaskName, Boolean.TRUE).start();
// Get all data collection components, currently only historical operation data collection. // Get all data collection components, currently only historical operation data collection.
collectors = ApplicationContextHolder.getBeansOfType(Collector.class); collectors = ApplicationContextHolder.getBeansOfType(Collector.class);
// Start reporting monitoring data thread.
ThreadUtil.newThread(this, "client.thread.reporting.task", Boolean.TRUE).start();
}
if (GlobalThreadPoolManage.getThreadPoolNum() > 0) {
log.info("Dynamic thread pool :: [{}]. The dynamic thread pool starts data collection and reporting. ", getThreadPoolNum());
} }
log.info("Dynamic thread pool :: [{}]. The dynamic thread pool starts data collection and reporting. ", getThreadPoolNum());
} }
@Override @Override
@ -121,6 +144,10 @@ public class ReportingEventExecutor implements Runnable, CommandLineRunner, Disp
Optional.ofNullable(collectVesselExecutor).ifPresent((each) -> each.shutdown()); Optional.ofNullable(collectVesselExecutor).ifPresent((each) -> each.shutdown());
} }
private void dynamicThreadPoolMonitor() {
threadPoolMonitors.forEach((beanName, monitor) -> monitor.collect());
}
/** /**
* Collect dynamic thread pool data and add buffer queues. * Collect dynamic thread pool data and add buffer queues.
*/ */

@ -20,6 +20,7 @@
<module>hippo4j-discovery</module> <module>hippo4j-discovery</module>
<module>hippo4j-example</module> <module>hippo4j-example</module>
<module>hippo4j-message</module> <module>hippo4j-message</module>
<module>hippo4j-monitor</module>
<module>hippo4j-server</module> <module>hippo4j-server</module>
<module>hippo4j-spring-boot</module> <module>hippo4j-spring-boot</module>
<module>hippo4j-tool</module> <module>hippo4j-tool</module>

Loading…
Cancel
Save