线程池监控这么做很简单
概述
最近公司项目生产上遇到了一个线程池的问题,由于线程池的配置参数开发人员没有根据实际情况考量,拍脑袋想了一个,将核心线程数和队列数都设置的很大,实际生产提交的任务很多,导致出现CPU很高,影响了其他的一些业务接口。回过头,复盘发现,我们没有对生产的线程池任务做一些监控,比如该任务执行了多长时间,在队列中等待了多少时间等等,那么有什么线程池的编程范式可以监控线程池的任务执行情况呢?目标
主要是为了实现下面的2个目标:线程池中任务在队列中等待的时间线程池中任务运行的时间
我们可以根据实际场景需求打印日志或者通过prometheus输出到监控系统中。解决方案
我们可以采用装饰者设计模式,写一个线程池任务的包装类,公司项目中所有要提交的任务必须要使用这个包装类去提交任务,定义任务的包装类代码如下:@Slf4j public class RunnableWrapper implements Runnable { // 实际要执行的线程任务 private Runnable task; // 线程任务被创建出来的时间 private long createTime; // 线程任务被线程池运行的开始时间 private long startTime; // 线程任务被线程池运行的结束时间 private long endTime; // 线程信息 private String taskInfo; // 当这个任务被创建出来的时候,就会设置他的创建时间 // 但是接下来有可能这个任务提交到线程池后,会进入线程池的队列排队 public RunnableWrapper(Runnable task, String taskInfo) { this.task = task; this.taskInfo = taskInfo; this.createTime = System.currentTimeMillis(); } // 当任务在线程池排队的时候,这个run方法是不会被运行的 // 但是当任务结束了排队,得到线程池运行机会的时候,这个方法会被调用 // 此时就可以设置线程任务的开始运行时间 @Override public void run() { this.startTime = System.currentTimeMillis(); // 此处可以通过调用监控系统的API,实现监控指标上报 // 用线程任务的startTime-createTime,其实就是任务排队时间 // 这边打印日志输出,也可以输出到监控系统中 log.info("任务信息: [{}], 任务排队时间: [{}]ms", taskInfo, startTime - createTime); // 接着可以调用包装的实际任务的run方法 task.run(); // 任务运行完毕以后,会设置任务运行结束的时间 this.endTime = System.currentTimeMillis(); // 此处可以通过调用监控系统的API,实现监控指标上报 // 用线程任务的endTime - startTime,其实就是任务运行时间 // 这边打印任务执行时间,也可以输出到监控系统中 log.info("任务信息: [{}], 任务执行时间: [{}]ms", taskInfo, endTime - startTime); } } 复制代码
后续我们提交线程池任务统一使用该任务包装类。使用案例
比如定义一个线程池如下, 核心线程数40, 最大线程数800,线程队列为500: @Bean(destroyMethod = "shutdown") public ThreadPoolExecutor sumTaskThreadPool() { return new ThreadPoolExecutor(50, 800, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(500)); } 复制代码
定义一个求和的任务:public class SumRunnable implements Runnable { @SneakyThrows @Override public void run() { int sum = 0; for (int i = 0; i < 100000; i++) { sum = sum + i; } Thread.sleep(1000); } } 复制代码
提交任务到线程池中:@PostConstruct public void init() throws InterruptedException { // 提交1000个线程任务 for (int i = 0; i < 1000; i++) { // 定义求和任务 SumRunnable sumRunnable = new SumRunnable(); // 包装求和任务 RunnableWrapper runnableWrapper = new RunnableWrapper(sumRunnable, "求和线程任务" + i); // 提交任务 threadPoolExecutor.submit(runnableWrapper); Thread.sleep(100); } } 复制代码
可以看到打印的结果如下图:
这样就可以打印出任务的排队时间和执行时间了。总结
不仅runnable可以进行这样的包装,对于Callable任务也可以进行包装。定义这样的包装类简单,难点在于如何根据打印出的日志进行分析和调整线程池参数。另外就是如何推动公司的同事都使用这样的线程池使用范式也是一大问题。
东方青苍的头饰有多贵?目测人均可入手。最近小编的朋友圈要被苍兰决要刷爆了!月尊大人的土味情话,这谁能顶得住呀!终于能理解男生为什么不能接受世界上没有奥特曼了,我们接受不了现实世界没有东方青苍呀!近几年随着香蜜三生三世等
酒桌上都有哪些暗号来来来,提一杯。如果你在酒桌上听到有人对你说这句话时,你会怎么做呢?听不懂?还是直接仰头一口闷呢?Nonono,这些做法都不对。在平时我们少不了会出去应酬聚会,总要喝上几杯,而在酒
曝李维嘉入驻浙江卫视成主持人,节目名单曝光,沈腾贾玲疑被换饿了吗?戳右边关注我们,每天给您送上最新出炉的娱乐硬核大餐!8月24日,有网友在社交平台上晒出王牌对王牌第八季嘉宾阵容,李维嘉竟出现在名单之中,还是以主持人的身份,引起了网友们的关
老话说入秋不吃肉,也要吃3豆,说的是哪3豆?怎么吃?三伏天闷热和潮湿的天气接近尾声,今年的秋天虽迟但到。一年四季中秋天总是显得格外匆忙,一场秋雨可能就来一场大降温。我们还没好好感受秋日的凉爽,似乎就过渡到寒冷的冬日。所以入秋后,我们
不装了?里根号航母灰溜溜返回母港,我国的话这次美听懂了随着我国不断发展壮大,使美国也感到了巨大的威胁与压力,因此,就促使美国想要通过各种方式对我国的发展进行遏制,以此来限制我国的发展。但是,随着我国的不断发展,在一定程度上,使美国在西
林志颖被曝手术恶化,妻子陈若仪删除11字动态,细节令人担心距林志颖车祸住院已经过去一个月,但近日却有多家媒体报道,称林志颖做完颜面手术后情况不是很理想,不但暂时不能张嘴吃饭,甚至讲话也不方便。为了补充身体恢复所需营养,医院选择插鼻胃管灌食
中国人的饭碗牢牢端在自己手中悠悠万事,吃饭为大。习近平总书记指出,粮食安全是国之大者我国是人口众多的大国,解决好吃饭问题,始终是治国理政的头等大事。100多亩扩大到500多亩,有了农机帮忙,望天田升级成高产田
第1章风起长安败了又败了消息传遍长安城,国人一片哗然。长安城一座酒楼里,有一老人端起酒杯叹息道大唐这下怕是要丢脸咯!居然又输了,这些棋待诏还真是废物啊!又一青年学子猛地放下筷子愤愤不平。谁说不是
阳光玫瑰平价之后,一个县城的农业革命才刚开始编者按今年夏天,火了几年的阳光玫瑰经历了从高价难求到平价泛滥的市场转变。水果市场越来越快的变化,使得农户在信息上的滞后和农业种植的周期性之间的矛盾日益凸显。当规模基地的投资者已经在
京东系接棒董事会主席达达抱紧大腿达达与京东不但藕断丝连,还越发离不开彼此。8月23日,达达集团宣布,京东零售CEO辛利军将担任达达集团董事会主席,达达集团副总裁何辉剑升任达达集团总裁。前者来自京东集团,后者是达达
五育并举显成效素质教育结硕果为构建德智体美劳全面发展人才培养体系,充分发挥榜样的力量,近年来,湖南网络工程职业学院以立德树人为目标导向,坚持五育并举,推动教学科研与思想政治教育有机结合育德与育智相结合理论教育