代码
//dubbo 线程池数量监控
Class<?> clazz = Class.forName("com.alibaba.dubbo.rpc.protocol.dubbo.status.ThreadPoolStatusChecker");
Method check = clazz.getMethod("check");
Object result = check.invoke(clazz.newInstance());
logger.info(JSONObject.toJSONString(result));
原理
1. 获取 dubbo 提供的类的对象
2. 读数据即可
dubbo 提供的类
/**
* ThreadPoolStatusChecker
*/
@Activate
public class ThreadPoolStatusChecker implements StatusChecker {
@Override
public Status check() {DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();
Map<String, Object> executors = dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY);
StringBuilder msg = new StringBuilder();
Status.Level level = Status.Level.OK;
for (Map.Entry<String, Object> entry : executors.entrySet()) {String port = entry.getKey();
ExecutorService executor = (ExecutorService) entry.getValue();
if (executor != null && executor instanceof ThreadPoolExecutor) { // 校验是否是线程池
ThreadPoolExecutor tp = (ThreadPoolExecutor) executor;
boolean ok = tp.getActiveCount() < tp.getMaximumPoolSize() - 1;
Status.Level lvl = Status.Level.OK;
if (!ok) {
level = Status.Level.WARN;
lvl = Status.Level.WARN;
}
if (msg.length() > 0) {msg.append(";");
}
msg.append("Pool status:" + lvl
+ ", max:" + tp.getMaximumPoolSize()
+ ", core:" + tp.getCorePoolSize()
+ ", largest:" + tp.getLargestPoolSize()
+ ", active:" + tp.getActiveCount()
+ ", task:" + tp.getTaskCount()
+ ", service port:" + port);
}
}
return msg.length() == 0 ? new Status(Status.Level.UNKNOWN) : new Status(level, msg.toString());
}
}
字段阐明
测试数据
2020-07-09 17:27:02.893|INFO |dlct2FhXhVFR-39-81|xxx.common.filter.dubbo.AccessLogExtFilter.invoke:175||
{"level":"OK",
"message":"Pool status:OK, // 线程池状态:失常
max:500, // 最大数量
core:500, //core 数量
largest:51, // 线程池线程数量的峰值,线程池中已经有过的最大线程数量
active:1, // 沉闷数量,始终在变动
task:51, // 总任务数量 = 已实现工作数量 + 未实现工作数量
service port: 12029"}
dubbo 源码 -ThreadPoolStatusChecker
msg.append("Pool status:" + lvl
+ ", max:" + tp.getMaximumPoolSize()
+ ", core:" + tp.getCorePoolSize()
+ ", largest:" + tp.getLargestPoolSize()
+ ", active:" + tp.getActiveCount()
+ ", task:" + tp.getTaskCount()
+ ", service port:" + port);
jdk 源码 -ThreadPoolExecutor
1、getLargestPoolSize
largest:51, // 线程池线程数量的峰值,线程池中已经有过的最大线程数量
/**
* Returns the largest number of threads that have ever
* simultaneously been in the pool.
*
* @return the number of threads
*/
public int getLargestPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {return largestPoolSize;} finally {mainLock.unlock();
}
}
2、getTaskCount
总的工作数量 = 已实现工作数量 + 工作汇合里未实现工作数量
/**
* Counter for completed tasks. Updated only on termination of
* worker threads. Accessed only under mainLock.
*/
private long completedTaskCount; // 已实现工作数量
/**
* Returns the approximate total number of tasks that have ever been
* scheduled for execution. Because the states of tasks and
* threads may change dynamically during computation, the returned
* value is only an approximation.
*
* @return the number of tasks
*/
public long getTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers) {
n += w.completedTasks;
if (w.isLocked())
++n;
}
return n + workQueue.size(); // 已实现工作数量 + 工作汇合里未实现工作数量} finally {mainLock.unlock();
}
}
官网 api 解释
long getTaskCount()
返回曾打算执行的近似工作总数。
https://doc.yonyoucloud.com/d…