Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE #301] 添加JMX监控采集类型 #390

Merged
merged 5 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,19 @@ public enum CollectorTypeEnum {
*/
LOGGING,

/**
* Micrometer collect type.
*/
MICROMETER,

INTERNAL_LOGGING
/**
* Logging collect type.
*/
INTERNAL_LOGGING,

/**
* Jmx collect type.
*/
JMX

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,26 @@

package org.dromara.dynamictp.common.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;




/**
* ThreadPoolStats related
*
* @author yanhom
* @since 1.0.0
**/
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里需要构造函数,但是不知道加这两个注解(加了@builder原因)好还是新增一个类复制这些属性好

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没看到哪儿需要构造函数呢

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没看到哪儿需要构造函数呢

MXBean 里面成员对象需要构造函数

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

了解了,要不去掉@builder吧,用的地方好像就一处

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

了解了,要不去掉@builder吧,用的地方好像就一处

OK,我改下

@EqualsAndHashCode(callSuper = true)
public class ThreadPoolStats extends Metrics {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.dromara.dynamictp.core.monitor.collector.LogCollector;
import org.dromara.dynamictp.core.monitor.collector.MetricsCollector;
import org.dromara.dynamictp.core.monitor.collector.MicroMeterCollector;
import org.dromara.dynamictp.core.monitor.collector.jmx.JMXCollector;
import org.springframework.util.CollectionUtils;

import java.util.List;
Expand All @@ -48,9 +49,11 @@ private CollectorHandler() {
MetricsCollector microMeterCollector = new MicroMeterCollector();
LogCollector logCollector = new LogCollector();
InternalLogCollector internalLogCollector = new InternalLogCollector();
JMXCollector jmxCollector = new JMXCollector();
COLLECTORS.put(microMeterCollector.type(), microMeterCollector);
COLLECTORS.put(logCollector.type(), logCollector);
COLLECTORS.put(internalLogCollector.type(), internalLogCollector);
COLLECTORS.put(jmxCollector.type(), jmxCollector);
}

public void collect(ThreadPoolStats poolStats, List<String> types) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@

package org.dromara.dynamictp.core.monitor.collector;

import cn.hutool.core.bean.BeanUtil;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.common.em.CollectorTypeEnum;
import org.dromara.dynamictp.common.entity.ThreadPoolStats;
import org.dromara.dynamictp.common.util.CommonUtil;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
Expand Down Expand Up @@ -61,7 +61,7 @@ public void collect(ThreadPoolStats threadPoolStats) {
if (Objects.isNull(oldStats)) {
GAUGE_CACHE.put(threadPoolStats.getPoolName(), threadPoolStats);
} else {
BeanUtil.copyProperties(threadPoolStats, oldStats);
BeanUtils.copyProperties(threadPoolStats, oldStats);
}
gauge(GAUGE_CACHE.get(threadPoolStats.getPoolName()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* 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 org.dromara.dynamictp.core.monitor.collector.jmx;

import lombok.extern.slf4j.Slf4j;
import org.dromara.dynamictp.common.em.CollectorTypeEnum;
import org.dromara.dynamictp.common.entity.ThreadPoolStats;
import org.dromara.dynamictp.core.monitor.collector.AbstractCollector;
import org.springframework.beans.BeanUtils;

import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* ThreadPoolStatsInfo related
*
* @author <a href = "mailto:kamtohung@gmail.com">KamTo Hung</a>
*/
@Slf4j
public class JMXCollector extends AbstractCollector {

public static final String DTP_METRIC_NAME_PREFIX = "dtp.thread.pool";

/**
* thread pool stats map
*/
private static final Map<String, ThreadPoolStats> GAUGE_CACHE = new ConcurrentHashMap<>();

@Override
public void collect(ThreadPoolStats threadPoolStats) {
if (GAUGE_CACHE.containsKey(threadPoolStats.getPoolName())) {
ThreadPoolStats poolStats = GAUGE_CACHE.get(threadPoolStats.getPoolName());
BeanUtils.copyProperties(threadPoolStats, poolStats);
} else {
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName(DTP_METRIC_NAME_PREFIX + ":name=" + threadPoolStats.getPoolName());
ThreadPoolStatsJMX stats = new ThreadPoolStatsJMX(threadPoolStats);
server.registerMBean(stats, name);
} catch (JMException e) {
log.error("collect thread pool stats error", e);
}
GAUGE_CACHE.put(threadPoolStats.getPoolName(), threadPoolStats);
}
}

@Override
public String type() {
return CollectorTypeEnum.JMX.name().toLowerCase();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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 org.dromara.dynamictp.core.monitor.collector.jmx;

import org.dromara.dynamictp.common.entity.ThreadPoolStats;

import java.beans.ConstructorProperties;

/**
* @author <a href = "mailto:kamtohung@gmail.com">KamTo Hung</a>
*/
public class ThreadPoolStatsJMX implements ThreadPoolStatsMXBean {

private ThreadPoolStats threadPoolStats;

@ConstructorProperties({"threadPoolStats"})
public ThreadPoolStatsJMX(ThreadPoolStats threadPoolStats) {
this.threadPoolStats = threadPoolStats;
}

@Override
public ThreadPoolStats getThreadPoolStats() {
return this.threadPoolStats;
}

@Override
public void setThreadPoolStats(ThreadPoolStats threadPoolStats) {
this.threadPoolStats = threadPoolStats;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 org.dromara.dynamictp.core.monitor.collector.jmx;

import org.dromara.dynamictp.common.entity.ThreadPoolStats;

import javax.management.MXBean;


/**
* ThreadPoolStatsMXBean related
*
* @author <a href = "mailto:kamtohung@gmail.com">KamTo Hung</a>
*/
@MXBean
public interface ThreadPoolStatsMXBean {

/**
* get thread pool stats
*
* @return thread pool stats
*/
ThreadPoolStats getThreadPoolStats();

/**
* set thread pool stats
*
* @param threadPoolStats thread pool stats
*/
void setThreadPoolStats(ThreadPoolStats threadPoolStats);

}
14 changes: 7 additions & 7 deletions test/test-core/src/test/resources/dynamic-tp-demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ spring:
enabled: true
enabledBanner: true # 是否开启banner打印,默认true
enabledCollect: true # 是否开启监控指标采集,默认false
collectorTypes: micrometer,logging # 监控数据采集器类型(logging | micrometer | internal_logging),默认micrometer
collectorTypes: jmx,micrometer,logging # 监控数据采集器类型(logging | micrometer | internal_logging),默认micrometer
logPath: /home/logs # 监控日志数据路径,默认 ${user.home}/logs
monitorInterval: 5 # 监控时间间隔(报警判断、指标采集),默认5s
configType: yml # 配置文件类型
executors: # 动态线程池配置,都有默认值,采用默认值的可以不配置该项,减少配置量
executors: # 动态线程池配置,都有默认值,采用默认值的可以不配置该项,减少配置量
- threadPoolName: testRunTimeoutDtpExecutor
executorType: common # 线程池类型common、eager:适用于io密集型
corePoolSize: 1
Expand All @@ -25,7 +25,7 @@ spring:
preStartAllCoreThreads: false # 是否预热所有核心线程,默认false
runTimeout: 200 # 任务执行超时阈值,目前只做告警用,单位(ms)
queueTimeout: 100 # 任务在队列等待超时阈值,目前只做告警用,单位(ms)
taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口
taskWrapperNames: [ "ttl" ] # 任务包装器名称,集成TaskWrapper接口
- threadPoolName: testQueueTimeoutDtpExecutor
executorType: common # 线程池类型common、eager:适用于io密集型
corePoolSize: 1
Expand All @@ -41,7 +41,7 @@ spring:
preStartAllCoreThreads: false # 是否预热所有核心线程,默认false
runTimeout: 200 # 任务执行超时阈值,目前只做告警用,单位(ms)
queueTimeout: 100 # 任务在队列等待超时阈值,目前只做告警用,单位(ms)
taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口
taskWrapperNames: [ "ttl" ] # 任务包装器名称,集成TaskWrapper接口
- threadPoolName: testRejectedQueueTimeoutCancelDtpExecutor
executorType: common # 线程池类型common、eager:适用于io密集型
corePoolSize: 1
Expand All @@ -57,7 +57,7 @@ spring:
preStartAllCoreThreads: false # 是否预热所有核心线程,默认false
runTimeout: 200 # 任务执行超时阈值,目前只做告警用,单位(ms)
queueTimeout: 100 # 任务在队列等待超时阈值,目前只做告警用,单位(ms)
taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口
taskWrapperNames: [ "ttl" ] # 任务包装器名称,集成TaskWrapper接口
- threadPoolName: eagerDtpThreadPoolExecutor
executorType: eager # 线程池类型common、eager:适用于io密集型
corePoolSize: 1
Expand All @@ -73,7 +73,7 @@ spring:
preStartAllCoreThreads: false # 是否预热所有核心线程,默认false
runTimeout: 200 # 任务执行超时阈值,目前只做告警用,单位(ms)
queueTimeout: 100 # 任务在队列等待超时阈值,目前只做告警用,单位(ms)
taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口
taskWrapperNames: [ "ttl" ] # 任务包装器名称,集成TaskWrapper接口
- threadPoolName: priorityDtpThreadPoolExecutor
executorType: priority # 线程池类型common、eager:适用于io密集型
corePoolSize: 1
Expand All @@ -88,4 +88,4 @@ spring:
preStartAllCoreThreads: false # 是否预热所有核心线程,默认false
runTimeout: 10000 # 任务执行超时阈值,目前只做告警用,单位(ms)
queueTimeout: 10000 # 任务在队列等待超时阈值,目前只做告警用,单位(ms)
taskWrapperNames: ["ttl"] # 任务包装器名称,集成TaskWrapper接口
taskWrapperNames: [ "ttl" ] # 任务包装器名称,集成TaskWrapper接口