一、Prometheus通过JMX采集metrics有两种方式:
1、in-process(推荐的),在进程内部读取JMX数据,使用-javaagent的premain(),在main方法执行之前register JMX和一些默认的Explorer,并启动一个HttpServer将从JMX收集过来的metrics转换成Http协议,供Prometheus周期性的Pull抓取。
2、独立进程,通过JMX的RMI接口读取数据并转化成Http协议,优点:有升级不用重启被采集对象的进程,缺点:多维护一个进程且不能监控进程的metrics(如:内存、CPU,即in-process的默认Explorer)。
二、javaagent(java探针:javaagent+字节码操作框架,asm,javassist)
javaagent在java.long.instrument包中,可在java程序运行时动态修改系统中Class的类型。其中的premain方法是在java虚拟机启动时在main()方法执行之前被调起,可以拦截用户类,但是有些系统类先于agent启动会拦不到。
三、SystemClassLoader
java -cp ** HelloApp时的装载顺序,当执行java命令时SystemClassLoader会先进行装载->链接->初始化然后再调用main(),由此推测premain应该是在main()的装载类之前被调用的。
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