我们知道可以利用jcmd的方式获取jfr的数据,可以主动dump,也可以运行一段时间dump下来。
目前这两种可以说解决了很多的场景。
- 可以主动的触发获取。
- 可以预期运行时长来获取。
但是如果遇到程序退出等情况,应该怎么处理呢。
程序正常退出
以上的两种方式都是在程序没有退出的时候有用,但是如果程序是可以正常退出的,选择时间或者人为的主动dump。这个都是碰运气的事情。
jfr也设计到了这种场景。
dumponexit
这个参数默认是false,可以设置为true。就可以在程序正常退出后获取到jfr文件。
程序异常退出
dumponexit解决了程序正常退出的情况。但是我们也常常遇到非正常的情况,例如oom kill,或者程序调度导致了kill -9的情况。这种时候已经不是jvm程序本身控制的了,无法dump到数据。
jfr并没有解决这个问题,我们可以通过一些参数做到部分满足
maxage
maxsize
maxage是控制文件保留时间的。
maxsize是控制jfr文件大小的。
通过这两个参数,我们可以控制把数据获取的更接近一些。
例如maxage是5min,我们可以获取到5分钟前的数据。这个数据并没有直接给到我们制定的文件夹下。
jfr会把临时的文件写入到tmp目录下,等到时间到了,或者文件大小到了,然后进行合并成一个jfr文件,新的文件会继续生成。
我们去tmp目录下就可以获取到最近一次的数据,虽然不知道最新的情况,但是问题的出现往往是有时间相关的,问题总是慢慢的变得严重,根据最后的现在和以前的数据也可以推测出问题。
这种也只能通过时间等参数,获取一个比较接近的值。我们所以用streaming来获取更实时的数据。
import jdk.jfr.Configuration;
import jdk.jfr.consumer.RecordingStream;
import java.io.IOException;
import java.text.ParseException;
public class JfrStream {
public static void main(String[] args) throws IOException, ParseException {
Configuration config = Configuration.getConfiguration("default");
try (var es = new RecordingStream(config)) {
es.onEvent("jdk.CPULoad", System.out::println);
es.onEvent("jdk.ThreadDump",System.out::println);
es.start();
}
}
}
streaming的能力可以保证获取到数据里面进行处理,这里的标准输出,可以改成socket传输等等。这样就可以把数据推送到远程,数据就是实时的了,不用再纠结maxage等限制了。如果程序退出后,就可以看到运行时的情况。这个的麻烦之处在于需要自己写代码,而且需要jdk14。之前的jdk还没有这个能力。
小结
jfr获取数据的能力有以下几条
- 主动dump
- 设置运行时间自动dump
- dumponexit
- maxage,maxsize的设置可以帮助我们程序意外退出的时候获取临时数据。
- 编写streaming的code
共同学习,写下你的评论
评论加载中...
作者其他优质文章