java线程池监控
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java线程池监控,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3255字,纯文字阅读大概需要5分钟。
内容图文
![java线程池监控](/upload/InfoBanner/zyjiaocheng/1318/6ed244b8c95a49ed8f8c0ef55fe68670.jpg)
原因
最近在完善公司的基础发布平台的时候,使用到了一线程去做一些异步的事情,在开发环境和测试环境验证没有任何问题,但是在程序在生产运行一段时间后,发现没有得到自己想要的结果,为此开始了漫长的排查bug的之路,因为用到了一些线程,但是实际又没有对这些线程足够的监控,所以在排查问题的时候也是历经艰难险阻;
原始代码
protected ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
/**
* 同步应用的jenkins状态
*/
public void threadASyncAppJenkinsStatus() {
executorService.scheduleAtFixedRate(() -> {
List<ArchitectureApp> architectureApps = architectureAppMapper.listArchitectureApp();
architectureApps.parallelStream().forEach(architectureApp -> syncJenkinsBuild(architectureApp.getName(), ArchitectureType.APP));
}, 0, 6, TimeUnit.SECONDS);
}
/**
* 同步组件的jenkins状态
*/
public void syncComponentJenkinsStatus() {
executorService.scheduleAtFixedRate(() -> {
List<ArchitectureComponent> architectureComponents = architectureComponentMapper.listArchitectureComponent();
architectureComponents.parallelStream().forEach(architectureComponent -> syncJenkinsBuild(architectureComponent.getName(), ArchitectureType.COMPONENT));
}, 0, 6, TimeUnit.SECONDS);
}
这是其中一部分的代码,做的事情很简单,程序每隔6s就去轮询组件和应用的状态,然后后面我会通过websocket同步到前端页面。这是一段很简单的代码,很难想象这段代码可能出错。但是事与愿违,通过开发和测试环境的测试,在上到生产运行了两天发现前端页面的jenkins状态并没有同步。而通过查看日志,也没法观察问题出在哪,所以只能另寻他法;
ExecutorsMonitor线程监控类
以下是我们开发的一个线程池工具类,该工具类扩展ScheduledThreadPoolExecutor实现了线程池监控功能,能实时将线程池使用信息打印到日志中,方便我们进行问题排查、系统调优。具体代码如下
@Slf4j class ExecutorsMonitor extends ScheduledThreadPoolExecutor { private ConcurrentHashMap<String, Date> startTimes; private String poolName; /** * 调用父类的构造方法,并初始化HashMap和线程池名称 * * @param corePoolSize 线程池核心线程数 * @param poolName 线程池名称 */ public ExecutorsMonitor(int corePoolSize, String poolName) { super(corePoolSize); this.startTimes = new ConcurrentHashMap<>(); this.poolName = poolName; } /** * 线程池延迟关闭时(等待线程池里的任务都执行完毕),统计线程池情况 */ @Override public void shutdown() { super.shutdown(); } /** * 线程池立即关闭时,统计线程池情况 */ @Override public List<Runnable> shutdownNow() { return super.shutdownNow(); } /** * 任务执行之前,记录任务开始时间 */ @Override protected void beforeExecute(Thread t, Runnable r) { startTimes.put(String.valueOf(r.hashCode()), new Date()); } /** * 任务执行之后,计算任务结束时间 */ @Override protected void afterExecute(Runnable r, Throwable t) { Date startDate = startTimes.remove(String.valueOf(r.hashCode())); Date finishDate = new Date(); long diff = finishDate.getTime() - startDate.getTime(); // 统计任务耗时、初始线程数、核心线程数、正在执行的任务数量、已完成任务数量、任务总数、队列里缓存的任务数量、池中存在的最大线程数、最大允许的线程数、线程空闲时间、线程池是否关闭、线程池是否终止 log.info(String.format(this.poolName + "-pool-monitor: Duration: %d ms, PoolSize: %d, CorePoolSize: %d, Active: %d, Completed: %d, Task: %d, Queue: %d, LargestPoolSize: %d, MaximumPoolSize: %d, KeepAliveTime: %d, isShutdown: %s, isTerminated: %s", diff, this.getPoolSize(), this.getCorePoolSize(), this.getActiveCount(), this.getCompletedTaskCount(), this.getTaskCount(), this.getQueue().size(), this.getLargestPoolSize(), this.getMaximumPoolSize(), this.getKeepAliveTime(TimeUnit.MILLISECONDS), this.isShutdown(), this.isTerminated())); } public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, String poolName) { return new ExecutorsMonitor(corePoolSize, poolName); } }
后来在生产终于定位问题,发现线程内部后来停止,同时发现的还有报错,通过查阅资料发现,原来线程发生异常后会退出,通过try catch很好的解决了这个问题
原文:https://www.cnblogs.com/clovejava/p/10053916.html
内容总结
以上是互联网集市为您收集整理的java线程池监控全部内容,希望文章能够帮你解决java线程池监控所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。