java动态加载
有时候我们线上的程序跑出了意想不到的效果,想破头都不知道为什么,如果杀掉jvm,则环境破坏了啥都看不到,咋办,可用的就是java的动态加载技术,可用在jvm运行的时候,动态的替换其中的某个类,我们可以添加点日志之类的,看看到底是哪里的问题,那么,这神奇的一切,要怎么进行了?
什么地方可以用
在不重启JVM的前提下进行闭包内执行逻辑的特定修改,如果返回值,如加日志等。
这种技术实现的基础就是java的instrument功能,
- Java.lang.instrument.Instrumentation
– redefineClasses、 retransformClasses
- This method is used to replace the definition of a class without reference to the existing class file bytes, as one might do when recompiling from source for fix-and-continue debugging. Where the existing class file bytes are to be transformed (for example in bytecode instrumentation) retransformClasses should be used.
– How to get the class
- Update the java file and compile
- Manupulate the class file
另外还需要可以attach到jvm上的接口, Sun公司提供的扩展API
- Java attach api
- com.sun.tools.attach
– Class VirtualMachine
» VirtualMachine.list
» VirtualMachine.attach
» VirtualMachine.loadAgent
» VirtualMachine.detach
– Class VirtualMachineDescriptor
– Class AttachProvider
然后有很多可以参考的工具:
- ASM
– ASM是一个JAVA字节码分析、创建和修改的开源应用框架。
-
- ASM 可以直接产生二进制 class 文件
- 可以在类被加载入 Java 虚拟机之前动态改变类行为
- Btrace
-
基于ASM、Java Attach Api、Instruments的Java语言的安全并提供动态追踪服务的工具
-
最最牛逼的当然是阿里的出品,
Arthas
Arthas 是Alibaba开源的Java诊断工具
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
是否有一个全局视角来查看系统的运行状况?
有什么办法可以监控到JVM的实时运行状态?
https://alibaba.github.io/arthas/quick-start.html
https://www.cnblogs.com/meituantech/p/10456037.html