jfr的收集

2020-10-29 03:01:30 蜻蜓队长

我们知道可以利用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获取数据的能力有以下几条

  1. 主动dump
  2. 设置运行时间自动dump
  3. dumponexit
  4. maxage,maxsize的设置可以帮助我们程序意外退出的时候获取临时数据。
  5. 编写streaming的code
点击查看更多内容

以上内容来自于网络,如有侵权联系即删除
相关文章

上一篇: 初试Vue3-手动实现render挂载

客服紫薇:15852074331
在线咨询
客户经理