//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.讀數據便可html
dubbo提供的類java
/** * 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()); } }
測試數據api
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源碼-ThreadPoolStatusCheckerapp
msg.append("Pool status:" + lvl + ", max:" + tp.getMaximumPoolSize() + ", core:" + tp.getCorePoolSize() + ", largest:" + tp.getLargestPoolSize() + ", active:" + tp.getActiveCount() + ", task:" + tp.getTaskCount() + ", service port: " + port);
jdk源碼-ThreadPoolExecutoride
一、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(); } }
二、getTaskCount
總的任務數量=已完成任務數量 + 任務集合裏未完成任務數量ui
/** * 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解釋this
long getTaskCount() 返回曾計劃執行的近似任務總數。