SpringBoot-技术专区-实战方案-应用监控线程池
背景
废话不多说,做这个监控的背景很简单,我们的项目都是以spring boot框架为基础开发的,代码里所有的异步线程都是通过@Async标签标注的,并且标注的时候都是指定对应线程池的,如果不知@Async标注的,可以参考@Async异步线程池用法总结, 如果你用的不是spring,就参考上文提到的公众号文章就好。再回到背景,我们当时经常遇到的问题就是这些线程池的队列满了之后,新的异步任务无法添加进去的错误,因此我们想对所有这种类型的线程池进行监控。
监控方式
再来介绍一下我们最终采用的方式 —— spring boot + statsd, 通过添加以下代码就可以使statd能够读取/metrics接口中所有的指标并发送监控数据到statsd后端,statsd并不是本篇文章的重点,之后有时间再细讲这部分的配置。
@Bean
public MetricsEndpointMetricReader metricsEndpointMetricReader(final MetricsEndpoint metricsEndpoint) {
return new MetricsEndpointMetricReader(metricsEndpoint);
}
代码及效果
我们所需要做的就是向/metrics接口添加线程池的指标,庆幸的是spring boot提供了良好的扩展机制,只需要实现PublicMetrics接口,实现其中的metrics方法你就能在/metrics中看到你新增的指标,上代码:
@Component
public class AsyncThreadPoolMetrics implements PublicMetrics {
public static final Logger LOG = LoggerFactory.getLogger(AsyncThreadPoolMetrics.class);
private Map<String, ThreadPoolTaskExecutor> targetAsyncThreadPool;
private static final String pattern = "async.task.%s.%s";
@Autowired
ApplicationContext context;
@Override
public Collection<Metric<?>> metrics() {
try {
if(targetAsyncThreadPool == null || targetAsyncThreadPool.size() == 0) {
targetAsyncThreadPool = context.getBeansOfType(ThreadPoolTaskExecutor.class);
}
Collection<Metric<?>> result = new ArrayList<>();
for (Map.Entry<String, ThreadPoolTaskExecutor> entry: targetAsyncThreadPool.entrySet()) {
ThreadPoolTaskExecutor executor = entry.getValue();
result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "aciveCount"), executor.getActiveCount(), new Date()));
result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "currentPoolSize"), executor.getPoolSize(), new Date()));
result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "maxPoolSize"), executor.getMaxPoolSize(), new Date()));
result.add(new Metric<Number>(String.format(pattern, entry.getKey(), "currentSizeInQueue"),
executor.getThreadPoolExecutor().getQueue().size(), new Date()));
}
return result;
} catch (Exception e) {
LOG.error("Async thread pool monitor exception", e);
}
return Collections.emptyList();
}
}
从上面的代码可以看出,我们监控的是多个线程池,原因很简单,为了使多种类型异步任务不互相影响,我们配置了多个线程池,多个线程池有不同的名字区分。
其实代码很简单,首先从容器中找到所有实现ThreadPoolTaskExecutor的bean,也就是我们要监控的线程池对象,取出正在活动的线程数,线程池的大小,配置最大可容纳的线程数以及当前排队的任务,当然还有很多其他指标,大家都可以试试,我只是选出当时我们需要的指标。当我们访问此时应用的/metrics,效果如下,红色框标注的便是我们添加的指标:
SpringBoot-技术专区-实战方案-应用监控线程池的更多相关文章
- 通过micrometer实时监控线程池的各项指标
通过micrometer实时监控线程池的各项指标 前提 最近的一个项目中涉及到文件上传和下载,使用到JUC的线程池ThreadPoolExecutor,在生产环境中出现了某些时刻线程池满负载运作,由于 ...
- 开源动态可监控线程池DynamicTp介绍
前言 使用线程池 ThreadPoolExecutor 过程中你是否有以下痛点呢? 代码中创建了一个 ThreadPoolExecutor,但是不知道那几个核心参数设置多少比较合适 凭经验设置参数值, ...
- Java利用线程工厂监控线程池
目录 ThreadFactory 监控线程池 扩展线程池 扩展线程池示例 优化线程池大小 线程池死锁 线程池异常信息捕获 ThreadFactory 线程池中的线程从哪里来呢?就是ThreadFoct ...
- 使用Spring开发和监控线程池服务
第1步:添加maven 项目 第2步:添加依赖库 将Spring的依赖添加到Maven的pom.xml文件中. 1 2 3 4 5 6 7 8 9 10 11 <!-- Spring 3 dep ...
- 用 ThreadPoolExecutor/ThreadPoolTaskExecutor 线程池技术提高系统吞吐量(附带线程池参数详解和使用注意事项)
1.概述 在Java中,我们一般通过集成Thread类和实现Runnnable接口,调用线程的start()方法实现线程的启动.但如果并发的数量很多,而且每个线程都是执行很短的时间便结束了,那样频繁的 ...
- Java并发编程实战 第8章 线程池的使用
合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...
- Java并发编程原理与实战三十七:线程池的原理与使用
一.简介 线程池在我们的高并发环境下,实际应用是非常多的!!适用频率非常高! 有过使用过Executors框架的朋友,可能不太知道底层的实现,这里就是讲Executors是由ThreadPoolExe ...
- java并发编程实战:第八章----线程池的使用
一.在任务和执行策略之间隐性耦合 Executor框架将任务的提交和它的执行策略解耦开来.虽然Executor框架为制定和修改执行策略提供了相当大的灵活性,但并非所有的任务都能适用所有的执行策略. 依 ...
- 《Java并发编程实战》第八章 线程池的使用 读书笔记
一.在任务与运行策略之间的隐性解耦 有些类型的任务须要明白地指定运行策略,包含: . 依赖性任务.依赖关系对运行策略造成约束.须要注意活跃性问题. 要求线程池足够大,确保任务都能放入. . 使用线程封 ...
随机推荐
- Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
一.extrack-tex-webpack-plugin作用:为了抽离css样式,防止将样式打包在js中引起页面样式加载错乱的现象二.使用 npm install extract-webpack-pl ...
- bounds与frame的区别及setBounds的使用
转自http://www.cocoachina.com/ios/20140925/9755.html 在iOS开发中经常遇到两个词Frame和bounds,本文主要阐述Frame和bound的区别,尤 ...
- 第01章 Spring概述
第01章 Spring概述 1.Spring概述 ①Spring是一个开源框架 ②Spring为简化企业级开发而生,使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能.同样的 ...
- SPOJ1693 COCONUTS - Coconuts
传送门[洛谷] 自闭QAQ 什么玩意QAQ 不是很理解到底在干啥 问了巨佬以后大概是这个样子的 可以看出是最小割模型 对于每一个人 反悔的话就是代价+1 那么连接(s,i) (i,t)分别表示他最后选 ...
- Win7 ODBC驱动 Excel (转)
“控制面板-管理工具-数据源(ODBC)”,打开“ODBC数据源管理器”窗口,然后“添加”,打开“创建新数据源”的窗口,最后选择Microsoft Access Driver(*.mdb)选项,往后等 ...
- list去重方法
list去重 方法1:利用循环去重 s= [1,1,2,2,2,3,4,4] res= [] for i in s: if i not in res: res.append(i) print(res) ...
- [CSP-S模拟测试]:Lost My Music(凸包)
题目描述 小$w$在天堂看到了一棵世界树.世界树上有$n$个节点,其中$1$节点为根,每个节点有一个正整数权值$c_i$.现在小$w$想要对每个节点$u$求出它的祖先$v$中$\frac{c_v-c_ ...
- 2018-2019-2 20175120 实验五《Java网络编程》实验报告
实验报告封面 课程:Java程序设计 班级:1751班 姓名:彭宇辰 学号:20175120 指导教师:娄嘉鹏 实验日期:2019年5月26日 实验时间:13:10 - 15:25 实验序号:20 实 ...
- Java JsonPath grab InvalidPathException in code, you must be catching Java 7's java.nio.file.InvalidPathException instead of JsonPath's com.jayway.jsonpath.InvalidPathExceptio
I am using JsonPath and am able to parse my data and get the values when the path provided is correc ...
- PHP的Session机制解析 2
在鸟哥的博客看到对php session的过期时间的一篇文章,在此记录. 原文地址:http://www.laruence.com/2012/01/10/2469.html 以下是鸟哥博客原文: 今天 ...