一、Prometheus通过JMX采集metrics有两种方式:

1、in-process,在进程内部读取JMX数据,使用-javaagent的premain(),在main方法执行之前register JMX和一些默认的Explorer,并启动一个HttpServer将从JMX收集过来的metrics转换成Http协议,供Prometheus周期性的Pull抓取。

2、独立进程,通过JMX的RMI接口读取数据并转化成Http协议,优点:有升级不用重启被采集对象的进程,缺点:多维护一个进程

二、javaagent(java探针:javaagent+字节码操作框架,asm,javassist)

javaagent在java.long.instrument包中,可在java程序运行时动态修改系统中Class的类型。其中的premain方法是在java虚拟机启动时在main()方法执行之前被调起,可以拦截用户类,但是有些系统类先于agent启动会拦不到。

三、SystemClassLoader

java -cp **  HelloApp时的装载顺序,当执行java命令时SystemClassLoader会先进行装载->链接->初始化然后再调用main(),由此推测premain应该是在装载之后被调用的。

prometheus jmx exporter原理-LMLPHP

JVM有两种加载器:启动类加载器和用户自定义加载器,启动类加载器加载方向是从bootstramp->user-defined,用户自定义:user-defined->bootstrap(双亲委派)

四、premain和agentmain区别

pemain只能在类加载之前修改字节码(类AOP的拦截),加载完成之后只能通过重新创建ClassLoader的方式重新加载。
agentmain可以不用添加启动参数,可以在运行后(加载完成)修改,并且不需要重新创建加载器,很强大到用法限制比较多。

Ref:

https://www.jianshu.com/p/6096bfe19e41

https://www.jb51.net/article/91910.htm

02-14 23:05