Skip to content

线程池监控

1. 监控的具体指标

  1. 线程维度:核心线程数、最大线程数、活跃线程数、历史最大线程数等
  2. 任务维度:总任务数、排队任务数、已完成任务数、拒绝任务数等
  3. 性能维度:任务平均耗时、线程空闲(保活)时间、线程池负载率等

Executor框架里的ThreadPoolExecutor类中提供了获取这些指标数据的API:

  1. poo1.getcorePoosize()- 核心线程数
  2. poo1.getMaximumPoolsize()-最大线程数
  3. poo1.getActivecount()- 活跃线程数(正在执行的线程数)
  4. poo1.getQueue().size()-队列中等待的任务数
  5. pool.getcompletedTaskcount()-已完成任务数
  6. pool.getTaskCount()-总任务数
  7. pool.getLargestPoolSize()-运行的最大任务数

2. 指标采集的方式

采集方式一般两种:实时采集与定时采集。

2.1 实时采集

  1. 自定义带监视功能的线程池类(继承ThreadPoolExecutor)
  2. 监控位埋点(任务执行前、任务执行后、线程池终止后)

注意

实时采集是通过在线程池预先"埋点",对每个运行的任务实时采集统计,对性能有影响

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. 总结

没有监控的线程池相当于没有消防报警的大厦;
埋点实时监控,迅速反映但对性能有影响; 定时监控,数据有延迟但降低了对性能的影响。
完善的监控体系:高峰期扩容、低谷期节能地健康运行(削峰填谷)。