线程池监控
1. 监控的具体指标
- 线程维度:核心线程数、最大线程数、活跃线程数、历史最大线程数等
- 任务维度:总任务数、排队任务数、已完成任务数、拒绝任务数等
- 性能维度:任务平均耗时、线程空闲(保活)时间、线程池负载率等
Executor框架里的ThreadPoolExecutor类中提供了获取这些指标数据的API:
- poo1.getcorePoosize()- 核心线程数
- poo1.getMaximumPoolsize()-最大线程数
- poo1.getActivecount()- 活跃线程数(正在执行的线程数)
- poo1.getQueue().size()-队列中等待的任务数
- pool.getcompletedTaskcount()-已完成任务数
- pool.getTaskCount()-总任务数
- pool.getLargestPoolSize()-运行的最大任务数
2. 指标采集的方式
采集方式一般两种:实时采集与定时采集。
2.1 实时采集
- 自定义带监视功能的线程池类(继承ThreadPoolExecutor)
- 监控位埋点(任务执行前、任务执行后、线程池终止后)
注意
实时采集是通过在线程池预先"埋点",对每个运行的任务实时采集统计,对性能有影响
java
public class MonitorThreadPoolExecutor extends ThreadPoolExecutor {
public MonitorThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
}
@Override
protected void terminated() {
super.terminated();
}
}
java
2.2 定时采集
SpringBoot项目为演示案例:
2. CommandLineRunner, ApplicationRunner两个接口在SpringBoot应用启动后自动执行,通过实现他们的run()方法可以完成初始化逻辑、提交后台任务等。
3. CommandLineRunner -run- 循环不断的往线程池中提交任务(间隔1s/次) 4. ApplicationRunner -run- 定时采集线程池的指标数据(首次间隔5s、间隔10s/次)
3. 总结
没有监控的线程池相当于没有消防报警的大厦;
埋点实时监控,迅速反映但对性能有影响; 定时监控,数据有延迟但降低了对性能的影响。
完善的监控体系:高峰期扩容、低谷期节能地健康运行(削峰填谷)。