线程池监控-bytebuddy-agent模式

2021/04/21 1091点热度 2人点赞 0条评论

项目地址:https://github.com/yxkong/agent

目前已实现对线程池、jvm的监控;

主要是在线程池创建时,对线程池进行增强,将线程池强引用到bootstrap-load-client-0.1.jar中的ThreadPoolMonitorData里。 使用此包的前提是线程池是固定资源,启动后不会销毁,如果动态创建线程池并销毁,需要调用shutdown或者shutdowNow,这块已实现对对强引用的解除,否则因为这块强引用导致资源无法释放,没法被gc回收

bootstrap-load-client

此模块需要打成jar包

  • 引入项目中;

  • 配置bootstrap ClassLoader加载

monitor-agent

此模块需要打成jar包,当一个agent使用 启动参数配置

-javaagent:/Users/yxk/git/agent/monitor-agent/target/monitor-agent-0.1.jar=127.0.0.1,8888 -Xbootclasspath/a:/Users/yxk/git/agent/bootstrap-load-client/target/bootstrap-load-client-0.1.jar

说明:

  • monitor-agent-0.1.jar 为agent包

  • bootstrap-load-client-0.1.jar 为Bootstrap ClassLoader加载的包,在增强ThreadPoolExecutor的时候,必须是启动类加载

com.yxkong.agent目录结构

ByteBuddyAgent 为主类

  • 增强ThreadPoolExecutor类

  • 初始化httpServer

advice 为 具体的增强

dto 为传输包装

httpserver

  • 实现了http服务(参考zabbix的jmx_exporter)

  • 功能服务必须继承Collector,同时在构造方法里设置methodName,

  • 实现collect 接口,就是具体要干的事,以及对应的返回参数

  • 在ByteBuddyAgent.initHttpServer()方法中实例化一个对象并且register() 如 new ThreadPoolCollector().register();

主要实现功能

  • JVMCollector jvm的监控

  • StackCollector 当前栈信息收集

  • ThreadPoolCollector 线程池收集

  • ThreadPoolModify 线程池部分信息修改

注意事项:

  • 线程池的ThreadFactory最好使用bootstrap-load-client-0.1.jar的NamedThreadFactory

  • 否则无法获取线程池的名称和描述

  • 针对没有使用NamedThreadFactory的ThreadPoolExecutor使用对象的hashCode做为key

测试

图片

MonitorTest  控制台输出:

获取ThreadPoolMonitorData的类加载器:null   #bootstrap classLoader 被屏蔽了,返回的是null获取ThreadPoolMonitorData收集的线程池:{}获取ThreadPoolMonitor的类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2线程池pool执行中1:biz-pool-3-thread-1线程池pool执行中2:biz-pool-3-thread-2线程池pool执行中3:biz-pool-3-thread-3线程池executorService执行中1:pool-1-thread-1线程池启动完再获取收集的线程池:{"616881582":{"executor":{"activeCount":0,"threadFactory":{},"largestPoolSize":1,"poolSize":1,"taskCount":1,"rejectedExecutionHandler":{},"corePoolSize":0,"completedTaskCount":1,"terminating":false,"maximumPoolSize":2147483647,"queue":[],"shutdown":false,"terminated":false},"name":"616881582","desc":"未使用提供的NamedThreadFactory"},"biz":{"executor":{"activeCount":0,"threadFactory":{"name":"biz","desc":"业务执行线程池"},"largestPoolSize":3,"poolSize":3,"taskCount":3,"rejectedExecutionHandler":{},"corePoolSize":5,"completedTaskCount":3,"terminating":false,"maximumPoolSize":10,"queue":[],"shutdown":false,"terminated":false},"name":"biz","desc":"业务执行线程池"}}

jvm 数据获取 http://10.214.12.38:8090/jvm

{    "data": {        "JVM": {            "specVersion": "1.8",            "unLoadedClassCount": 0,            "javaVersion": "1.8.0_281",            "jitName": "HotSpot 64-Bit Tiered Compilers",            "jitTime": 1,            "pid": "10866",            "totalLoadedClassCount": 3038,            "version": "25.281-b09",            "specVendor": "Oracle Corporation",            "specName": "Java Virtual Machine Specification",            "loadedClassCount": 3038,            "vendor": "Oracle Corporation",            "name": "Java HotSpot(TM) 64-Bit Server VM",            "startTime": 1618885248,            "runTime": 19        },        "memory": {            "oldGenMemoryUsage: ": {                "init": 179306496,                "usedPercent": 5.7213474E-6,                "committed": 179306496,                "max": 2863661056,                "used": 16384            },            "permGenMemoryUsage: ": {                "init": 0,                "usedPercent": 0.0,                "committed": 16646144,                "max": -1,                "used": 15378040            },            "permGenMemoryPeakUsage: ": {                "init": 0,                "usedPercent": 0.0,                "committed": 16646144,                "max": -1,                "used": 15378072            },            "nonHeapMemoryUsage": {                "init": 2555904,                "usedPercent": 0.0,                "committed": 23134208,                "max": -1,                "used": 21547992            },            "edenSpaceMemoryUsage": {                "init": 67108864,                "usedPercent": 0.011954648,                "committed": 67108864,                "max": 1409286144,                "used": 16847520            },            "codeCacheMemoryUsage: ": {                "init": 2555904,                "usedPercent": 0.015820567,                "committed": 3997696,                "max": 251658240,                "used": 3981376            },            "heapMemoryUsage": {                "init": 268435456,                "usedPercent": 0.0064246687,                "committed": 257425408,                "max": 3817865216,                "used": 24528520            },            "oldGenMemoryPeakUsage: ": {                "init": 179306496,                "usedPercent": 5.7213474E-6,                "committed": 179306496,                "max": 2863661056,                "used": 16384            },            "codeCacheMemoryPeakUsage: ": {                "init": 2555904,                "usedPercent": 0.015820567,                "committed": 3997696,                "max": 251658240,                "used": 3981376            },            "survivorSpaceMemoryUsage: ": {                "init": 11010048,                "usedPercent": 0.72662354,                "committed": 11010048,                "max": 11010048,                "used": 8000160            },            "survivorSpaceMemoryPeakUsage: ": {                "init": 11010048,                "usedPercent": 0.72662354,                "committed": 11010048,                "max": 11010048,                "used": 8000160            },            "edenSpaceMemoryPeakUsage": {                "init": 67108864,                "usedPercent": 0.04761905,                "committed": 67108864,                "max": 1409286144,                "used": 67108864            }        },        "thread": {            "threadCount": 13,            "resetPeakThreadCount": 13,            "daemonThreadCount": 5,            "peakThreadCount": 13        },        "GC": {            "fullGCName": "PS MarkSweep",            "YGCTime": 5,            "fullGCTime": 0,            "fullGCCount": 0,            "YGCCount": 1,            "YoungGCName": "PS Scavenge"        }    },    "message": "执行成功!",    "status": "1",    "timestamp": 1618885268328}

线程池数据获取 http://10.214.12.38:8090/threadPool

{    "message": "执行成功!",    "status": "1",    "data": {        "biz": {            "name": "biz",            "desc": "业务执行线程池",            "activeCount": 0,            "largestPoolSize": 3,            "poolSize": 3,            "taskCount": 3,            "corePoolSize": 5,            "completedTaskCount": 3,            "terminating": false,            "maximumPoolSize": 10,            "queueSize": 0,            "shutdown": false,            "terminated": false        },        "java.util.concurrent.ThreadPoolExecutor@892965953": {            "name": "java.util.concurrent.ThreadPoolExecutor@892965953",            "desc": "未使用提供的NamedThreadFactory",            "activeCount": 0,            "largestPoolSize": 1,            "poolSize": 1,            "taskCount": 1,            "corePoolSize": 0,            "completedTaskCount": 1,            "terminating": false,            "maximumPoolSize": 2147483647,            "queueSize": 0,            "shutdown": false,            "terminated": false        },        "execute-pool-1": {            "name": "execute-pool-1",            "desc": "default",            "activeCount": 1,            "largestPoolSize": 1,            "poolSize": 1,            "taskCount": 1,            "corePoolSize": 5,            "completedTaskCount": 0,            "terminating": false,            "maximumPoolSize": 5,            "queueSize": 0,            "shutdown": false,            "terminated": false        }    },    "timestamp": 1618917221721}

线程池修改 http://10.214.12.38:8090/threadPool/modify?key=execute-pool-1&coreSize=3&maximumPoolSize=100

{    "message": "执行成功!",    "status": "1",    "data": {        "name": "execute-pool-1",        "desc": "default",        "activeCount": 3,        "largestPoolSize": 3,        "poolSize": 3,        "taskCount": 3,        "corePoolSize": 3,        "completedTaskCount": 0,        "terminating": false,        "maximumPoolSize": 100,        "queueSize": 0,        "shutdown": false,        "terminated": false    },    "timestamp": 1618917392869}

启动命令:

java -Xbootclasspath/a:/Users/yxk/git/agent/bootstrap-load-client/target/bootstrap-load-client-0.1.jar -javaagent:/Users/yxk/git/agent/monitor-agent/target/monitor-agent-0.1.jar   -jar springboot-test-2.3.2.RELEASE.jar

使用zabbix或者别的监控工具,将对应的接口配置进去,完全可以实现对线程池的监控

项目地址:https://github.com/yxkong/agent

yxkong

这个人很懒,什么都没留下

文章评论